C# 将XML转换为ViewModel中的LINQ以填充模型
我有一个XML文件,我想用它来填充模型。我的XML中有多个研究,我的目标是用所有研究名称填充一个列表,当选择研究名称并按下提交按钮时,应用程序将导航到一个新窗口,但会携带所选研究的其余XML数据 XMLC# 将XML转换为ViewModel中的LINQ以填充模型,c#,xml,wpf,linq,mvvm,C#,Xml,Wpf,Linq,Mvvm,我有一个XML文件,我想用它来填充模型。我的XML中有多个研究,我的目标是用所有研究名称填充一个列表,当选择研究名称并按下提交按钮时,应用程序将导航到一个新窗口,但会携带所选研究的其余XML数据 XML 螺旋体2 Z:\SPIROMICS\Human\u Scans\Dispatch\u Received\NO\u BACKUP\u DONE\u HERE\IMPORT BLF Z:\BLF\Human Scans\Dispatch Received\IMPORT Model.cs usin
螺旋体2
Z:\SPIROMICS\Human\u Scans\Dispatch\u Received\NO\u BACKUP\u DONE\u HERE\IMPORT
BLF
Z:\BLF\Human Scans\Dispatch Received\IMPORT
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
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间DICOM_Importer.Models
{
///
///APPIL实验室内所有活动研究的模型
///
公共课程研究:InotifyProperty变更,IDataErrorInfo
{
私人字符串studytle;
私有字符串导入目录;
公共字符串studytle
{
获取{return studytile;}
设置
{
studytle=值;
房地产变更(“StudyTitle”);
}
}
公共字符串导入目录
{
获取{return importDirectory;}
设置
{
importDirectory=值;
OnPropertyChanged(“ImportDirectory”);
}
}
#区域属性ChangedEventHandler
//创建可用于处理数据更改的PropertyChangedEventHandler变量
公共事件属性更改事件处理程序属性更改;
//创建在属性更改时处理数据更新的方法。
私有void OnPropertyChanged(字符串propertyChanged)
{
//引入您创建的事件处理程序变量,并将其分配给此方法“handler”变量
PropertyChangedEventHandler处理程序=PropertyChanged;
//如果处理程序的值不为null,这意味着属性已更改,则将新值交给要更改的处理程序
if(处理程序!=null)
{
处理程序(此,新PropertyChangedEventArgs(propertyChanged));
}
}
#端区
#区域数据错误信息
///
///通过IDataErrorInfo接口设置的错误消息的Getter和Setter
///
公共字符串错误
{
得到;
设置
}
//传入的列名将是我们要验证的研究对象的属性
//此验证正在查看StudyTitle属性。如果StudyTitle属性为“null”或仅为空白,则我们将添加错误消息
//“研究标题不能为null或空”否则,如果StudyTitle正常,则错误消息将为“null”
公共字符串此[string columnName]
{
得到
{
如果(columnName==“StudyTitle”)
{
if(String.IsNullOrWhiteSpace(studytile))
{
Error=“研究标题不能为null或空”;
}
其他的
{
错误=null;
}
}
返回误差;
}
}
#端区
}
}
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; }
}
}
}
使用DICOM\u.Models;
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Xml.Linq;
名称空间DICOM_Importer.ViewModels
{
内部类HomeViewModel
{
//设置将在此类中使用的某些变量
//“专用只读”正在设置将附加研究对象的研究数据类型
私人只读研究;
公共字符串studytle;
///
///初始化CustomServiceWModel类的新实例
///
公共HomeViewModel()
{
字符串路径_to_debug_folder=Directory.GetCurrentDirectory();
string path=path.GetFullPath(path.Combine(路径到调试文件夹,@“.\..”)+@“Data\Studies.xml”;
//“path”变量是包含所有研究数据的XML文件的路径,我们首先检查文件是否存在,然后创建
//序列化程序类的实例,并使用该类中的反序列化方法在XML文件上使用该类
//我们为其创建了“私有只读”变量的研究对象的实例。
if(File.Exists(path))
{
XElement xe=XElement.Load(路径);
var x=xe.Elements();
foreach(x中的var标记)
{
studytle=tag.FirstNode.ToString();
}
}
}
///
///创建客户的实例
///
公共研究
{
获取{返回研究;}
}
}
}
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>
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命名空间:DICOM\u Importer.Views”
mc:Ignorable=“d”
背景=“黄金”
Title=“DICOM导入器”Height=“385”Width=“600”>
DICOM进口商
积极研究
挑选
我知道我的ViewModel不是cor
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>
// If proeprty values are expected to change
// and this changes are required to propagate to the view
// this class must implement INotifyPropertyChanged
public class ViewModel
{
private void ReadXml(string filePath)
{
var xmlRootElement = XElement.Load(path);
List<Studies> studies = xmlRootElement.Decendants("Study")
.Select(CreateModelFromStudyXmlNode)
.ToList();
this.Studies = new ObservableCollection<Study>(studies);
}
private Study CreateModelFromStudyXmlNode(XElement studyXmlNode)
{
var newStudy = new Study();
newStudy.StudyTitle = studyXmlNode.Element("StudyTitle").Value;
newStudy.ImportDirectory = studyXmlNode.Element("ImportDirectory").Value;
return newStudy;
}
public ObservableCollection<Study> Studies { get; set; }
}
public class Study
{
public string StudyTitle { get; set; }
public string ImportDirectory { get; set; }
}
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<ListBox ItemsSource="{Binding Studies}" >
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type Study}">
<TextBlock Text="{Binding StudyTitle}" />
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
</Window>