I have an XML file that I want to use to populate a model. I have multiple studies within my XML and my goal is to populate a list with all the study names and when the study name is selected and submit button is pressed then the application will navigate to a new window but carry the rest of the XML data from the selected study.
XML
<?xml version="1.0" encoding="utf-8" ?>
<Studies>
<Study>
<StudyTitle>SPIROMICS2</StudyTitle>
<ImportDirectory>Z:\SPIROMICS\Human_Scans\Dispatch_Received\NO_BACKUP_DONE_HERE\IMPORT</ImportDirectory>
</Study>
<Study>
<StudyTitle>BLF</StudyTitle>
<ImportDirectory>Z:\BLF\Human Scans\Dispatch Received\IMPORT</ImportDirectory>
</Study>
</Studies>
Model.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DICOM_Importer.Models
{
/// <summary>
/// Model for all active studies within the APPIL lab
/// </summary>
public class Studies : INotifyPropertyChanged, IDataErrorInfo
{
private string studyTitle;
private string importDirectory;
public string StudyTitle
{
get { return studyTitle; }
set
{
studyTitle = value;
OnPropertyChanged("StudyTitle");
}
}
public string ImportDirectory
{
get { return importDirectory; }
set
{
importDirectory = value;
OnPropertyChanged("ImportDirectory");
}
}
#region PropertyChangedEventHandler
//Create a PropertyChangedEventHandler variable that you can use to handle data changing
public event PropertyChangedEventHandler PropertyChanged;
//create the method that will handle the updating of data if a property is changed.
private void OnPropertyChanged(string propertyChanged)
{
//bring in the event handler variable that you created and assign it to this methods 'handler' variable
PropertyChangedEventHandler handler = PropertyChanged;
//if the the handler is not null, which means the property has been changed, then hand in the new value to the handler to be changed
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyChanged));
}
}
#endregion
#region DataErrorInfo
/// <summary>
/// Getter and Setter for the Error message that we setup through the IDataErrorInfo interface
/// </summary>
public string Error
{
get;
set;
}
//the column name passed in will be a property on the Studies Object that we want to validate
//this validatation is looking at the StudyTitle property. If the StudyTitle property is 'null' or just white space then we are going to add the error message
//"Study Title cannot be null or empty" Otherwise if StudyTitle is fine the error message will be 'null'
public string this[string columnName]
{
get
{
if (columnName == "StudyTitle")
{
if (String.IsNullOrWhiteSpace(StudyTitle))
{
Error = "Study Title cannot be null or empty";
}
else
{
Error = null;
}
}
return Error;
}
}
#endregion
}
}
ViewModel.cs
using DICOM_Importer.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DICOM_Importer.ViewModels
{
internal class HomeViewModel
{
//setting up some variable that will be use through this class
// the private read only is setting up a Studies data type that will have a studies object attached to it
private readonly Studies studies;
public string studyTitle;
/// <summary>
/// Initializes a new instance of the CustomerViewModel class
/// </summary>
public HomeViewModel()
{
string path_to_debug_folder = Directory.GetCurrentDirectory();
string path = Path.GetFullPath(Path.Combine(path_to_debug_folder, @"..\..\")) + @"Data\Studies.xml";
//the 'path' variable is the path to the XML file containing all Studies data, we first just check the file does exist, we then create
//an instance of the Serializer class and use that class on the XML file using the Deserialize method from the class. Then attached the data to an
//instance of a Studies object that we created a 'private readonly' variable for.
if (File.Exists(path))
{
XElement xe = XElement.Load(path);
var x = xe.Elements();
foreach (var tag in x)
{
studyTitle = tag.FirstNode.ToString();
}
}
}
/// <summary>
/// creates an instance of a Customer
/// </summary>
public Studies Studies
{
get { return studies; }
}
}
}
The View.xaml
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICOM_Importer.Views"
mc:Ignorable="d"
Background="Gold"
Title="DICOM Importer" Height="385" Width="600">
<Grid Style="{StaticResource gridBackground}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Column="1" Grid.Row="0" Style="{StaticResource homeTitle}">DICOM IMPORTER</Label>
<Image x:Name="appil_logo" Grid.Column="0" Grid.Row="0" Grid.RowSpan="4" Source="/assets/appil_logo.png"/>
<Border Grid.Column="1" Grid.Row="0" Style="{StaticResource studyListHeader}" Width="Auto">
<Label Style="{StaticResource studyListText}">Active Studies</Label>
</Border>
<ListBox Name="activeStudiesListBox" Grid.Column="1" Grid.Row="2" >
<Label Content="{Binding Studies.StudyTitle}" />
</ListBox>
<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource buttonStyle}">Select</Button>
</Grid>
</Window>
I know my ViewModel is not correct, that is mainly where my problems are. Could anyone please show me how I can use this XML file along with the Model to populate my ListBox with the studyTitle's in my View. I want to be able to add a new study to the XML file and have it be included in the listbox in the View.