Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XML Datagrid根元素-foreach循环_C#_Xml_Wpf_Linq_Datagrid - Fatal编程技术网

C# XML Datagrid根元素-foreach循环

C# XML Datagrid根元素-foreach循环,c#,xml,wpf,linq,datagrid,C#,Xml,Wpf,Linq,Datagrid,我想将我的所有信息从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,

我想将我的所有信息从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;
    }
}
我说了一个错误

无法使用“非发票成员”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;

}
private void DataGrid\u已加载(对象发送方,RoutedEventArgs e)
{
//getElement是此对象的奇怪名称:)
XDocument getElement=XDocument.Load(“details.xml”);
//在foreach之外创建ColmNames列表以供以后使用
var items=新列表();
foreach(getElement.Root.Elements(“用户”)中的var npc)
{
字符串id=npc.Attribute(“id”).Value;
字符串名称=npc.Attribute(“Name”).Value;
字符串姓氏=npc.Attribute(“姓氏”).Value;
字符串Computer=npc.Attribute(“Computer”).Value;
添加(新列名(id、姓名、姓氏、计算机));
}
//最后,获取对网格的引用并设置要使用的ItemsSource属性
//包含所有项目的完整列表
var grid=发送方作为数据网格;
grid.ItemsSource=项目;
}
你很接近

foreach (var npc in getElement.Descendants("user"))
对于给定的XML结构,它确实有效,并且是正确的。不过,请参见我答案的底部,了解一个重要的区别

问题是您正在设置
grid.ItemsSource=items
在您的
foreach
循环中,因此每次foreach循环时只添加一个项,并且您总是只得到数据网格中的最后一个项

此外,您还需要保留
foreach
循环之外的项目列表,否则它只存在于
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;

}
或者,你已经有了

foreach (var npc in getElement.Descendants("user"))
这里的主要区别是
。后代()
将获得名为“user”的任何节点,无论其嵌套深度如何
.Elements()
将只从当前节点(直接子节点)获取下一级

因此,尽管XML结构的工作原理似乎相同,但在XML结构发生变化(或场景/项目不同等)时,理解这种区别是很重要的


作为旁注,getElement是
XDocument
对象的奇怪名称;我通常只使用xDoc之类的东西


再更新一次-为什么不起作用?

当我意识到这是一个WPF数据网格,并且您正在加载一个本地XML文件时,我突然意识到您的网格没有显示任何内容,因为XDocument.Load()无法找到该文件

我在一个带有DataGrid的空WPF应用程序中用try/catch检查了这一点

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void DataGrid_Loaded(object sender, RoutedEventArgs e)
    {
        XDocument getElement = null;// = XDocument.Load(@"c:\dev\stackoverflow\DataGridWpf\DataGridWpf\details.xml");
        try
        {
            getElement = XDocument.Load(@"details.xml");
        } catch (Exception ex) {
            var test = ex.ToString();
        }

        // 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;
    }
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
已加载私有void数据网格(对象发送方,RoutedEventArgs e)
{
XDocument getElement=null;/=XDocument.Load(@“c:\dev\stackoverflow\DataGridWpf\DataGridWpf\details.xml”);
尝试
{
getElement=XDocument.Load(@“details.xml”);
}捕获(例外情况除外){
var测试=例如ToString();
}
//在foreach之外创建列名列表,以便以后使用
var items=新列表();
foreach(getElement.subjections(“用户”)中的var npc)
{
字符串id=npc.Attribute(“id”).Value;
字符串名称=npc.Attribute(“Name”).Value;
字符串姓氏=npc.Attribute(“姓氏”).Value;
字符串Computer=npc.Attribute(“Computer”).Value;
//您现在正在将一个项目添加到现有列表中,而不是每次添加一个新项目
添加(新列名(id、姓名、姓氏、计算机));
}
//最后,获取对网格的引用并设置要使用的ItemsSource属性
//包含所有项目的完整列表
var grid=发送方作为数据网格;
grid.ItemsSource=项目;
}
如果您单步执行,这段代码将抛出FileNotFound异常,如果未经处理,该异常将消失,您将得到一个空窗口

在我的例子中,完整路径起到了作用,网格很好地加载:


Perl的作者拉里·沃尔(Larry Wall)将懒惰描述为程序员的第一大美德。不要做超出你需要的工作(有人将不得不维护它……可能就是你)。因此

为什么不用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; }
  }

}
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
  DataGrid grid = (DataGrid) sender ;
  grid.ItemsSource = LoadUserDetails() ;
  return ;
}
将反序列化包装到方法中:

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 ;
    }
}
然后,您的方法看起来像:

[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; }
  }

}
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
  DataGrid grid = (DataGrid) sender ;
  grid.ItemsSource = LoadUserDetails() ;
  return ;
}

哪个更容易测试和/或维护?

感谢您的回复,我非常感谢您的回复,虽然现在datagrid中没有结果,但它对我帮助很大。要么是您复制了一些错误的代码,要么是出现了另一个问题;请用您现在的新代码更新您的问题,我们将看看是否可以解决它。请稍候,我发现了问题他的问题是XML加载本身。我已经尝试了完整路径和npc.XML,有什么问题吗?让我们看看你确定DataBind()吗正在调用..您是否已通过调试器并正在执行此代码。我觉得代码看起来不错。它只通过一次,但其余部分不会通过。通过什么一次,foreach循环?1.确保您的XML文件正确。2.确保正确重建解决方案并运行新代码。我明白了ting混淆了我要导入的名称空间。我使用System.Xml.Linq;使用System.Xml;使用System.Xml.Serialization;使用System.I导入
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
  DataGrid grid = (DataGrid) sender ;
  grid.ItemsSource = LoadUserDetails() ;
  return ;
}