我是c#的新手,它试图将XML文件导入到DataGrid中,但是到目前为止,我设法只导入了列标头,而没有导入节点内的数据。我不知道在运行时会从xml加载什么样的数据,它可以是任何东西,但是下面的示例是所有内容的总体结构。
我试图为我的问题寻找答案,但是我得到的一切都是针对我不在这里使用的DataGridView,所以所有搜索都比我想要的要多。任何帮助将不胜感激。标签的深度可以从1到40甚至更多。
我的XMLdata看起来像这样:
<Details>
<Record>
<Username>name</Username>
<FirstName>firstname</FirstName>
<LastName>lastname</LastName>
etc
.
.
.
</Record>
</Details>
我的Xaml
<DataGrid x:Name="DetailsGridTemplate" AlternatingRowBackground="AliceBlue" CanUserAddRows="True" CanUserDeleteRows="True"
ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible"
Height="380" Width="430" AutoGenerateColumns="False" IsReadOnly="True" Grid.ColumnSpan="2" Margin="0,0,0.4,0"
ItemsSource="{Binding}">
</DataGrid>
我的导入代码
private void InitGridFromXML(string xmlPath)
{
var data = XElement.Load(xmlPath);
// Set Grid data to row nodes (NOTE: grid = DataGrid member)
var elements = data.Elements("Item");
DetailsGridTemplate.ItemsSource = elements;
// Create grid columns from node attributes. A hashtable ensures
// only one column per attribute since this iterates through all
// attributes in all nodes. This way, the grid can handle nodes with
// mutually different attribute sets.
var cols = new Hashtable();
var rows = new Hashtable();
foreach (XElement node in data.Descendants("Item"))
{
foreach (XElement childNode in node.Descendants())
{
var col = childNode.Name.LocalName;
var row = childNode.Value;
// Only add col if it wasn't added before
if (!cols.Contains(col))
{
// Mark col as added
cols[col] = true;
rows[row] = true;
// Add a column with the title of the attribute and bind to its
// value
DetailsGridTemplate.Columns.Add(new DataGridTextColumn
{
Header = col,
});
DetailsGridTemplate.Items.Add(new DataGridRow
{
DataContext = row,
});
}
}
}
}
答案 0 :(得分:1)
最简单的方法是使用LINQ to XML。您可以将XElement
直接绑定到ItemsSource
。
ViewModel.cs
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
this.DataTable = new DataTable();
}
private void InitGridFromXML(string xmlPath)
{
var xmlEntities = XElement.Load(xmlPath).Elements().ToList();
var dataTable = new DataTable();
dataTable.Columns.AddRange(
xmlEntities
.FirstOrDefault()?
.Elements()
.Select(node => new DataColumn(node.Name.LocalName))
.ToArray());
foreach (XElement xElement in xmlEntities)
{
dataTable.Rows.Add(
xElement.Elements()
.Select(node => node.Value)
.ToArray());
}
this.DataTable = dataTable;
}
private DataTable dataTable;
public DataTable DataTable
{
get => this.dataTable;
set
{
this.dataTable = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindow.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<Grid>
<DataGrid AutoGenerateColumns="True"
ItemsSource="{Binding DataTable}" />
<Grid>
<Window>