C# 使用Linq将xml解析为ObservableCollection。使用wpf c将数据绑定到datagrid#
我是linq、wpf和C#的新手。我已经设法研究了一种实现功能组件的方法。我已经成功地攻击了数据绑定,但我正在与性能作斗争。我正在读取一个静态外部xml文件(即数据库),并希望使用wpf datagrid向用户显示它。另外一点信息是,我使用一个用户控制的wpf组合框来过滤网格中显示的数据库数据量。我想使用linq来完成这项任务,但我似乎无法让它正确执行 C#文件: {C# 使用Linq将xml解析为ObservableCollection。使用wpf c将数据绑定到datagrid#,c#,wpf,linq,data-binding,C#,Wpf,Linq,Data Binding,我是linq、wpf和C#的新手。我已经设法研究了一种实现功能组件的方法。我已经成功地攻击了数据绑定,但我正在与性能作斗争。我正在读取一个静态外部xml文件(即数据库),并希望使用wpf datagrid向用户显示它。另外一点信息是,我使用一个用户控制的wpf组合框来过滤网格中显示的数据库数据量。我想使用linq来完成这项任务,但我似乎无法让它正确执行 C#文件: { 公共部分类ReadDB:Window,INotifyPropertyChanged { 私有XDocument xmlDoc=n
公共部分类ReadDB:Window,INotifyPropertyChanged { 私有XDocument xmlDoc=null;
const string ALL=“ALL”
//构造函数
公共ReadDB()
{
初始化组件();
//加载xml
xmlDoc=XDocument.Load(“DataBase.xml”);
this.DataContext=this;
}
私人可观测收集;
公共可观测集合
{
获取{return\u col;}
设置
{
如果(_col==值)
返回;
_col=值;
OnPropertyChanged(()=>Col);
}
}
私人可观察收集(mfgCollection);;
公共可观测集合MFG集合
{
获取{return\u mfgCollection;}
设置
{
if(_mfgCollection==值)
返回;
_mfgCollection=值;
OnPropertyChanged(()=>MfgCollection);
}
}
私人可观测采集;
公共可观测的集合MfgNames
{
获取{返回此。mfgNames;}
设置
{
如果(此值.\u mfgNames==值)
返回;
这个。mfgNames=值;
OnPropertyChanged(()=>MfgNames);
}
}
#区域通知事件声明和定义
公共事件属性更改事件处理程序属性更改;
公共虚拟void OnPropertyChanged(表达式属性)
{
PropertyChangedEventHandler eventHandler=this.PropertyChanged;
if(eventHandler!=null)
{
var memberExpression=property.Body作为memberExpression;
eventHandler(这是新的PropertyChangedEventArgs(memberExpression.Member.Name));
}
}
#端区
公共类CMfgData:ReadDB
{
私有字符串_mfgName;
//私有可观察收集(pipeDataCollection);;
/*公共CMfgData(字符串mfgName、CPipeData pipeData)
{
_mfgName=mfgName;
_pipeData=pipeData;
}*/
#区域CMfgData属性定义
公共字符串MfgName
{
获取{return\u mfgName;}
设置
{
如果(_mfgName==值)
返回;
_mfgName=值;
OnPropertyChanged(()=>MfgName);
}
}
/*公共可观测收集管道数据收集
{
获取{return\u pipeDataCollection;}
设置
{
if(_pipeDataCollection==值)
返回;
_pipeDataCollection=值;
OnPropertyChanged(()=>PipeDataCollection);
}
}*/
#端区
}
公共类CPipeData:ReadDB
{
//PipeData属性声明
私有字符串_标称;
私有字符串_sched;
私有字符串_id;
私有字符串_od;
私有字符串_wt;
公共消费物价指数()
{
_“名义上”;
_sched=“”;
_id=“”;
_od=“”;
_wt=“”;
}
//建造师
公共CPipeData(字符串标称、字符串sched、字符串id、字符串od、字符串wt)
{
_标称=标称;
_sched=sched;
_id=id;
_od=od;
_wt=wt;
}
#区域CPipeData特性定义
公共字符串名词
{
获取{return\u nominal;}
设置
{
如果(_标称==值)
返回;
_标称值=额定值;
不动产变更(()=>名义);
}
}
公共字符串Sched
{
获取{return\u sched;}
设置
{
如果(_sched==值)
返回;
_sched=值;
OnPropertyChanged(()=>Sched);
}
}
公共字符串ID
{
获取{return\u id;}
设置
{
如果(_id==值)
返回;
_id=值;
OnPropertyChanged(()=>ID);
}
}
公共字符串OD
{
获取{return\u od;}
设置
{
如果(_od==值)
返回;
_od=值;
OnPropertyChanged(()=>OD);
}
}
公共字符串WT
{
获取{return}
设置
{
如果(_wt==值)
返回;
_wt=值;
OnPropertyChanged(()=>WT);
}
}
#端区
}
私有void mfgrComboBox1_SelectionChanged(对象发送方,SelectionChangedEventArgs e)
{
//更新数据库网格
如果(mfgrComboBox1.SelectedValue为字符串)
{
PopulateGrid(MFGRCombox1.SelectedValue作为字符串);
}
}
已加载私有无效窗口(对象发送器、路由目标)
{
/*MfgCollection=新的可观测集合(
来自xmlDoc.Root.Elements中的mfg(“mfg”)
namespace ReadPipeXMLDB
// Constructor
public ReadDB()
{
InitializeComponent();
// Load xml
xmlDoc = XDocument.Load("DataBase.xml");
this.DataContext = this;
}
private ObservableCollection<CPipeData> _col;
public ObservableCollection<CPipeData> Col
{
get { return _col; }
set
{
if (_col == value)
return;
_col = value;
OnPropertyChanged(() => Col);
}
}
private ObservableCollection<CMfgData> _mfgCollection;
public ObservableCollection<CMfgData> MfgCollection
{
get { return _mfgCollection; }
set
{
if (_mfgCollection == value)
return;
_mfgCollection = value;
OnPropertyChanged(() => MfgCollection);
}
}
private ObservableCollection<string> _mfgNames;
public ObservableCollection<string> MfgNames
{
get { return this._mfgNames; }
set
{
if (this._mfgNames == value)
return;
this._mfgNames = value;
OnPropertyChanged(() => MfgNames);
}
}
#region Notify Event Declaration and Definition
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged<T>(Expression<Func<T>> property)
{
PropertyChangedEventHandler eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
var memberExpression = property.Body as MemberExpression;
eventHandler(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
}
}
#endregion
public class CMfgData : ReadDB
{
private string _mfgName;
//private ObservableCollection<CPipeData> _pipeDataCollection;
/*public CMfgData(string mfgName, CPipeData pipeData)
{
_mfgName = mfgName;
_pipeData = pipeData;
}*/
#region CMfgData Property Definitions
public string MfgName
{
get { return _mfgName; }
set
{
if (_mfgName == value)
return;
_mfgName = value;
OnPropertyChanged(() => MfgName);
}
}
/* public ObservableCollection<CPipeData> PipeDataCollection
{
get { return _pipeDataCollection; }
set
{
if (_pipeDataCollection == value)
return;
_pipeDataCollection = value;
OnPropertyChanged(() => PipeDataCollection);
}
}*/
#endregion
}
public class CPipeData : ReadDB
{
// PipeData Property Declarations
private string _nominal;
private string _sched;
private string _id;
private string _od;
private string _wt;
public CPipeData()
{
_nominal = "";
_sched = "";
_id = "";
_od = "";
_wt = "";
}
// Constructor
public CPipeData(string nominal, string sched, string id, string od, string wt)
{
_nominal = nominal;
_sched = sched;
_id = id;
_od = od;
_wt = wt;
}
#region CPipeData Property Definitions
public string Nominal
{
get { return _nominal; }
set
{
if (_nominal == value)
return;
_nominal = value;
OnPropertyChanged(() => Nominal);
}
}
public string Sched
{
get { return _sched; }
set
{
if (_sched == value)
return;
_sched = value;
OnPropertyChanged(() => Sched);
}
}
public string ID
{
get { return _id; }
set
{
if (_id == value)
return;
_id = value;
OnPropertyChanged(() => ID);
}
}
public string OD
{
get { return _od; }
set
{
if (_od == value)
return;
_od = value;
OnPropertyChanged(() => OD);
}
}
public string WT
{
get { return _wt; }
set
{
if (_wt == value)
return;
_wt = value;
OnPropertyChanged(() => WT);
}
}
#endregion
}
private void mfgrComboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Update database grid
if (mfgrComboBox1.SelectedValue is string)
{
PopulateGrid(mfgrComboBox1.SelectedValue as string);
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
/*MfgCollection = new ObservableCollection<CMfgData>(
from mfg in xmlDoc.Root.Elements("Mfg")
//where mfg.Attribute("name").Value == comboValue
select new CMfgData
{
MfgName = mfg.Attribute("name").Value,
PipeDataCollection =
new ObservableCollection<CPipeData>
(from pipe in mfg.Elements("pipe")
select new CPipeData
{
Nominal = pipe.Element("Nominal").Value,
Sched = pipe.Element("Schedule").Value,
ID = pipe.Element("ID").Value,
OD = pipe.Element("OD").Value,
WT = pipe.Element("Wall_Thickness").Value
})
});*/
}
private void mfgrComboBox1_Loaded(object sender, RoutedEventArgs e)
{
// Make sure xml document has been loaded
if (xmlDoc != null)
{
ObservableCollection<string> tempCollection = new ObservableCollection<string>(
from n in xmlDoc.Root.Elements("Mfg").Attributes("name")
select n.Value);
// Add the additional "All" filter
tempCollection.Insert(0, ALL);
// Assign list to member property. This is done last so the property event gets fired only once
MfgNames = tempCollection;
PopulateGrid(ALL);
}
}
private void PopulateGrid(string comboValue)
{
if (mfgrComboBox1.Items.IndexOf(comboValue) > -1)
{
Col = new ObservableCollection<CPipeData>(
from mfg in xmlDoc.Root.Elements("Mfg")
where mfg.Attribute("name").Value == comboValue
from pipe in mfg.Elements("pipe")
select new CPipeData
{
Nominal = pipe.Element("Nominal").Value,
Sched = pipe.Element("Schedule").Value,
ID = pipe.Element("ID").Value,
OD = pipe.Element("OD").Value,
WT = pipe.Element("Wall_Thickness").Value
});
}
}
}
<Window x:Class="ReadPipeXMLDB.ReadDB"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Standard Pipe Sizes" Height="849" Width="949" Loaded="Window_Loaded">
<Grid>
<!-- Manufactuer filter combobox -->
<ComboBox Name="mfgrComboBox1"
ItemsSource="{Binding Path=MfgNames}"
SelectedIndex="0"
Height="23" Width="286"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="20,20,0,0" SelectionChanged="mfgrComboBox1_SelectionChanged" Loaded="mfgrComboBox1_Loaded" />
<!-- Units combobox -->
<ComboBox Height="23" HorizontalAlignment="Left" Margin="320,20,0,0" Name="dimensionsComboBox2" VerticalAlignment="Top" Width="87" />
<!-- Pipe database display grid -->
<DataGrid Name="dataGrid1" IsReadOnly="True" AutoGenerateColumns="False" Margin="20,60,20,20" ItemsSource="{Binding Col}">
<DataGrid.Columns>
<DataGridTextColumn Header="Nominal" Binding="{Binding Path=Nominal}"/>
<DataGridTextColumn Header="Schedule" Binding="{Binding Path=Sched}"/>
<DataGridTextColumn Header="ID" Binding="{Binding Path=ID}"/>
<DataGridTextColumn Header="OD" Binding="{Binding Path=OD}"/>
<DataGridTextColumn Header="Wall Thickness" Binding="{Binding Path=WT}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
<DBRoot>
<Mfg name="A Manufac">
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
</Mfg>
<Mfg name="B Manufac">
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
</Mfg>
</DBRoot>
public class Mfg
{
public string Name { get; private set; }
public ObservableCollection <CPipeData> pipes { ....
ItemsSounce="{binding ElementName=cbMfg Path=SelectedItem.Pipes}"
<Grid>
<Grid.DataContext>
<XmlDataProvider Source="DataBase.xml"/>
</Grid.DataContext>
<StackPanel>
<ComboBox ItemsSource="{Binding XPath=/DBRoot/Mfg}" Name="comboBox" SelectedIndex="0">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=@name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<DataGrid ItemsSource="{Binding ElementName=comboBox, Path=SelectedItem}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding XPath=Nominal}" Header="Nominal"/>
<DataGridTextColumn Binding="{Binding XPath=Schedule}" Header="Schedule"/>
<DataGridTextColumn Binding="{Binding XPath=OD}" Header="OD"/>
<DataGridTextColumn Binding="{Binding XPath=Wall_Thickness}" Header="Wall Thickness"/>
<DataGridTextColumn Binding="{Binding XPath=ID}" Header="ID"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>