我希望将所有信息从XML获取到Datagrid。
目前我有这个:
class ColumnNames
{
public string id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Computer { get; set; }
public ColumnNames(
string id,
string Name,
string Surname,
string Computer,
{
this.id = id;
this.Name = Name;
this.Surname = Surname;
this.Computer = Computer;
}
}
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
XDocument getElement = XDocument.Load("details.xml");
foreach (var npc in getElement.Descendants("user"))
{
string id = npc.Attribute("id").Value;
string Name = npc.Attribute("Name").Value;
string Surname = npc.Attribute("Surname").Value;
string Computer = npc.Attribute("Computer").Value;
var items = new List<ColumnNames>();
items.Add(new ColumnNames(id, Name, Surname, Computer));
var grid = sender as DataGrid;
grid.ItemsSource = items;
}
}
这是我的XML
<info>
<user id="1" Name="Max0" Surname="0test" Computer="0" />
<user id="2" Name="Max1" Surname="1test" Computer="1" />
<user id="3" Name="Max2" Surname="2test" Computer="2" />
<user id="4" Name="Max3" Surname="3test" Computer="3" />
<user id="5" Name="Max4" Surname="4test" Computer="4" />
<user id="6" Name="Max5" Surname="5test" Computer="5" />
</info>
我要做的是将根元素中的所有数据放入包含id,name,surname和computer列的数据网格中。我的问题是,目前它只获得第一个条目,当我尝试使用以下内容时:
foreach (var npc in getElement.Root("info"))
我说错误
“不能使用非可调用成员'System.Xml.Linq.XDocument.Root' 像一种方法。“
我不确定如何才能完成这项工作,我已经有一段时间试图解决这个问题,一些帮助就是很好。感谢。
更新:
这是大卫慷慨帮助我之后的新代码。虽然它仍然无效。
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
// getElement is a weird name for this object :)
XDocument getElement = XDocument.Load("details.xml");
// Create your List of ColmNames outside the foreach to use later
var items = new List<ColumnNames>();
foreach (var npc in getElement.Root.Elements("user"))
{
string id = npc.Attribute("id").Value;
string Name = npc.Attribute("Name").Value;
string Surname = npc.Attribute("Surname").Value;
string Computer = npc.Attribute("Computer").Value;
items.Add(new ColumnNames(id, Name, Surname, Computer));
}
// Finally, get a reference to the grid and set the ItemsSource property to use
// your full list containing all the items
var grid = sender as DataGrid;
grid.ItemsSource = items;
}
答案 0 :(得分:1)
你很亲密......
foreach (var npc in getElement.Descendants("user"))
实际上确实有效,并且是正确的,具有给定的XML结构。不过,请参阅我的答案的底部以获得重要的区别。
问题是您在grid.ItemsSource = items;
循环中设置foreach
,因此每次foreach循环时只添加一个项目,并且您最终只得到数据网格中的最后一项。
此外,您还需要保留foreach
循环之外的项目列表,否则它只在scope
内存在(只有foreach
)。
要解决此问题,您需要将grid.ItemsSource = items;
移至foreach
循环之后,并将列表创建移至foreach
循环之前:
// Your code
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
// getElement is a weird name for this object :)
XDocument getElement = XDocument.Load("details.xml");
// Create your List of ColumnNames outside the foreach to use later
var items = new List<ColumnNames>();
foreach (var npc in getElement.Descendants("user"))
{
string id = npc.Attribute("id").Value;
string Name = npc.Attribute("Name").Value;
string Surname = npc.Attribute("Surname").Value;
string Computer = npc.Attribute("Computer").Value;
// You are adding an item to the existing List<ColumnNames> now, not a new one each time
items.Add(new ColumnNames(id, Name, Surname, Computer));
}
// Finally, get a reference to the grid and set the ItemsSource property to use
// your full list containing all the items
var grid = sender as DataGrid;
grid.ItemsSource = items;
}
希望这有帮助!
关于您在XDocument
循环中更改foreach
调用的尝试,正如我所提到的,您确实让它正常工作......但要解释为什么更改的版本不起作用,既然我已经写过,请看下面的内容:
您的主要问题是XDocument
有一个Root
元素,在本例中为<info>
您正在使用的语法getElement.Root("info")
告诉编译器您要调用名为Root of XDocument的method
- 但该方法不存在。这是一个属性。这就是您的错误消息告诉您的内容。
要解决问题,
更改您的foreach
以使用.Elements()
的{{1}}方法,一切顺利:
XDocument
或者,就像你已经拥有它一样
foreach (var npc in getElement.Root.Elements("user"))
这里的主要区别是foreach (var npc in getElement.Descendants("user"))
将获得名为“user”的任何节点,无论它嵌套的深度如何; .Descendants()
只会从当前节点(直接子节点)下一级。
因此,虽然使用XML结构时它们的工作原理相同,但在XML结构发生更改(或者场景/项目不同等)的情况下理解这种区别非常重要。
作为旁注,getElement是.Elements()
对象的奇怪名称;我通常只使用像xDoc ......
再次更新 - 为什么这不起作用?
当我意识到这是一个WPF数据网格,并且你正在加载一个本地XML文件时,我突然意识到你的网格没有显示任何内容,因为XDocument.Load()无法找到该文件。
我在带有DataGrid的空WPF应用程序中使用try / catch检查了这一点。
XDocument
这段代码,如果您单步执行,将抛出FileNotFound异常,如果未处理就会死掉,最后会出现一个空窗口!
在我的情况下,完整路径完成了技巧,并且网格很好地加载:
答案 1 :(得分:0)
为什么不用XML序列化属性来装饰数据结构,例如:
[XmlRoot("info")]
public class InfoList
{
[XmlElement("user")]
public User[] Users { get ; set ; }
public class User
{
[XmlAttribute] public string id { get; set; }
[XmlAttribute] public string Name { get; set; }
[XmlAttribute] public string Surname { get; set; }
[XmlAttribute] public string Computer { get; set; }
}
}
在方法中包装反序列化:
static User[] LoadUserDetails()
{
XmlSerializer serializer = new XmlSerializer(typeof(InfoList)) ;
using ( Stream s = File.Open("details.xml",FileMode.Open,FileAccess.Read,FileShare.Read) )
{
InfoList instance = (InfoList) serializer.Deserialize(s) ;
return instance.Users ;
}
}
然后你的方法看起来像:
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
DataGrid grid = (DataGrid) sender ;
grid.ItemsSource = LoadUserDetails() ;
return ;
}
哪种更易于测试和/或维护?