C# 用XML文件动态填充Listview/Gridview

C# 用XML文件动态填充Listview/Gridview,c#,xml,wpf,gridview,C#,Xml,Wpf,Gridview,各位下午好!我现在正在努力学习cWPF大约两周,我遇到了一些谷歌至今没有帮助我解决的问题:/ 假设我有一个随机的XML文件: <?xml version="1.0" encoding="UTF-8"?> <XML> <ADRESSE> <NAME1>John</NAME1> <NAME2>Doe</NAME2> <STRASSE1>Heystreet</STRASSE

各位下午好!我现在正在努力学习cWPF大约两周,我遇到了一些谷歌至今没有帮助我解决的问题:/

假设我有一个随机的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<XML>
  <ADRESSE>
    <NAME1>John</NAME1>
    <NAME2>Doe</NAME2>
    <STRASSE1>Heystreet</STRASSE1>
    <STRASSE2>9</STRASSE2>
    <LAND>AUT</LAND>
    <PLZ>1050</PLZ>
    <ORT>Vienna</ORT>
  </ADRESSE>
</XML>
1和3是我的实际问题,我猜1和2是同一件事

所以基本上我想做的就是按下按钮,加载XML并为ADRESE的每个子级创建一列,列中包含当前子级的名称,并直接用XML内容填充它

我现在遇到的问题是:1 foreach循环只针对名为ADRESE的每个条目运行,而不是它的每个子元素,我只是不知道如何在不破坏任何语法的情况下获得它的子元素。我用元素尝试了它,但他不喜欢在循环中这样做。。所以现在,上面的XML只会创建一行而不是7行,因为文件中只有一个ADRESE条目

对于第二个问题,我想用XML的Childname来命名列,但是由于1的问题,它无法按预期工作。或者这种想法通常是错误的

第三个问题是柱的动态填充。就我所知,lv1.Items.Add{…}不接受上面的feldx,但认为它是自己的名称,并且没有正确填充,因为没有名为feldx的ColumnBinding。对于4,我需要像feldx=xele.Element@{0},ChildName.values这样的内容来获取列的正确内容

我真的试着自己去寻找和解决这个问题,但是我在XML或GridView上找到的所有东西,或者在mycsharp/msdn上找到的,要么只是静态硬编码的XAML入口和绑定,或者只是XML文件,在这些文件中,您知道哪些入口实际上是硬编码的。所以我只希望我的要求不要太露骨,有人能给我一些启发

编辑1:

    var rootele = rndfile.Root.Element("ADRESSE").Elements(); //<-- worked like a charm. My problem was that i tried to fiddle this into the foreach loop itself, which wasn't accepted somehow - so many thanks har07
    int counter = 0;
    foreach (XElement xele in rootele)
    {
        GridViewColumn gvc = new GridViewColumn();
        gvc.DisplayMemberBinding = new Binding("Feld"+counter); 
        gvc.Header = xele.Name.LocalName; 
        gv1.Columns.Add(gvc); 
        lv1.Items.Add(new { feld_x_ = xele.Element("Childelement of ADRESSE").Value }); // <-- for this i am trying to find a solution and post it again, or maybe someone else knows how to add a changing Binding Name  into the .Add()
        counter++;

    }
    lv1.View = gv1;

您的XML文件不正确

<NAME2>Doe</NAME3> 
应该是

<NAME2>Doe</NAME2>
你的foreach循环显然是告诉你通过每个循环

您可能希望尝试这种基于上面第2个链接精心编制的方法:

....
var columnValues = new List<string>();
foreach (XElement xele in rootele)
{
    GridViewColumn gvc = new GridViewColumn();
    gvc.DisplayMemberBinding = new Binding(String.Format("[{0}]", counter)); 
    gvc.Header = xele.Name.LocalName; 
    gv1.Columns.Add(gvc); 
    columnValues.Add((string)xele);
    counter++;
}
lv1.Items.Add(columnValues);
....

我现在只写这个问题的部分解决方案,这将需要比我想要的更多的硬编码,但总比什么都没有好-也许其他人需要它再次感谢har07


我真的很感激你能帮我做一个循环

啊哈,我只是编辑错了一点,xml很好,但是谢谢,我应该给你一个“解决的答案”点击,还是我只能给每个线程一次?因为您实际上解决了我循环的主要问题:更新了我对其余问题的答案。尽管如此,我还是建议提出一个新的问题,如果我的更新不适用于您,对于XML中只有一个条目的情况,这非常有效,但如果外部XML中有多个实例,则不会。我现在只是在玩这个问题,但我想知道为什么绑定只适用于您在String.Format上面编写的这个[{0}],counter。如果我尝试更改绑定名称,它根本不起作用?我不知何故假设,如果XML文件的条目被稍微打乱,它将不会按预期工作。我的意思是,上面的示例将值直接添加到创建的列中,根据列的绑定添加值。但是我已经帮了我很多忙,我将尝试用两个独立的foreach循环来解决这个问题:一个根据ADRESE的子对象数创建Listview列,另一个循环为整个XML文件中的每个ADRESE条目添加值,或者尝试将变量名以某种方式输入到lv1.add.Items命令1中,这是关于绑定的,是的意思s绑定到列值[计数器],您不能随意修改它。2这是因为我们只能通过这样做得到第一个(我故意这么想):rndfile.Root.ElementAddresse…注意元素而不是元素。如果您想要容纳多个,则需要彻底更改逻辑流,因为此时代码将再次添加重复的列,并且我建议重新思考一下逻辑,如果你需要进一步的建议,可以提出新的问题。
//approach 1 :
var chldNodes = rndfile.Descendants("ADRESSE").First().Elements();
//or approach 2 :
var chldNodes = rndfile.Root.Element("ADRESSE").Elements();
//then loop through childNodes
foreach (XElement xele in chldNodes)
....
var columnValues = new List<string>();
foreach (XElement xele in rootele)
{
    GridViewColumn gvc = new GridViewColumn();
    gvc.DisplayMemberBinding = new Binding(String.Format("[{0}]", counter)); 
    gvc.Header = xele.Name.LocalName; 
    gv1.Columns.Add(gvc); 
    columnValues.Add((string)xele);
    counter++;
}
lv1.Items.Add(columnValues);
....
        GridView gv1 = new GridView();
        XDocument rndfile = XDocument.Load(@"C:\Users\...\rndfile.xml");
        var rootele = rndfile.Descendants("ADRESSE").First().Elements();
        int counter = 0;
        //Create empty Listview depending on Sub-entrys of ADRESSE
        foreach (XElement xele in rootele)
        {

            GridViewColumn gvc = new GridViewColumn();
            gvc.DisplayMemberBinding = new Binding("Feld"+counter);//gets a Binding name Feld# for each child
            gvc.Header = xele.Name.LocalName; //Name my Columns after the <tags> of the childs
            gv1.Columns.Add(gvc);  //add the current Column to my Gridview
            counter++;

        } //Listview created

        //Fill my list for every single Parent-element in my XML file

            foreach (XElement xe in rndfile.Descendants("ADRESSE"))
            {

                 lv1.Items.Add(new
                    {
                        Feld0 = xe.Element("NAME1").Value,
                        Feld1 = xe.Element("NAME2").Value,
                        Feld2 = xe.Element("STRASSE1").Value,
                        Feld3 = xe.Element("STRASSE2").Value,
                        Feld4 = xe.Element("LAND").Value,
                        Feld5 = xe.Element("PLZ").Value,
                        Feld6 = xe.Element("ORT").Value
                    });

            }//List filled 
    <?xml version="1.0" encoding="UTF-8"?>
    <XML>
      <ADRESSE>
        <NAME1>John</NAME1>
        <NAME2>Doe</NAME2>
        <STRASSE1>Heystreet</STRASSE1>
        <STRASSE2>9</STRASSE2>
        <LAND>AUT</LAND>
        <PLZ>1050</PLZ>
        <ORT>Vienna</ORT>
      </ADRESSE>
      <ADRESSE>
        <LAND>AUT</LAND>
        <PLZ>1060</PLZ>
        <ORT>Vienna</ORT>
        <NAME1>Jane</NAME1>
        <STRASSE1>Wherestreet</STRASSE1>
        <STRASSE2>11</STRASSE2>
        <NAME2>Doe</NAME2>
      </ADRESSE>
    </XML>
lv1.Items.Add(new{ string.Format(@"Feld{0}", counter) = xe.Element(@"{0}", xele.Name.LocalName).Value}