使用XML文件动态填充Listview / Gridview

时间:2014-07-28 18:33:35

标签: c# xml wpf gridview

下午好的男生和女生!我正在尝试学习c#(WPF)大约2周,我遇到了一些问题,谷歌目前还没有帮助我解决这个问题:/

假设我有一个随机的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>

假装此XML有100个条目。

现在我将在我的XAML和一个按钮中有一个名为“lv1”的简单Listview。

        int counter = 0;
        GridView gv1 = new GridView();
        XDocument rndfile = XDocument.Load(@"C:\Users\...\random.xml");

        foreach (XElement xele in rndfile.Descendants("ADRESSE")) //#1
        {

            GridViewColumn gvc = new GridViewColumn();
            gvc.DisplayMemberBinding = new Binding("Feld"+counter); 
            gvc.Header = xele.Name.LocalName; // #2
            gv1.Columns.Add(gvc); 
            string feldx = string.Format(@"Feld{0}", counter);
           // MessageBox.Show(feldx+"||"+"Feld"+counter); //was for me to test if names are identical
            lv1.Items.Add(new { feldx = xele.Element("Childelement of ADRESSE").Value }); //#3+4
            counter++;

        }
        lv1.View = gv1;

1和3是我的实际问题,其中1和2是我猜的相同。

基本上我想要做的就是按下Button,加载XML并为每个ADRESSE子项创建一个包含当前Child名称的列,并直接用XML内容填充它。

我现在遇到的问题:#1 foreach循环只运行每个名为ADRESSE的条目,而不是每个子元素,我只是想弄清楚如何在不破坏任何语法的情况下获取它的孩子(尝试使用它Elements()但他不喜欢循环中的那些)..所以现在上面的XML只会创建一行而不是7行,因为文件中只有一个ADRESSE条目。

对于第二个问题,我想命名具有XML的子名称的列,但由于#1的问题,它不会按预期工作。 (或者这种想法通常是错误的吗?)

第三个问题是柱子的动态填充。据我所知,它lv1.Items.Add({...})不接受上面的feldx,但认为它是一个自己的名称,然后没有正确填充它,因为没有名为feldx的列绑定。对于#4,我需要类似feldx = xele.Element(@"{0}", ChildName).Value的内容来获取列的正确内容

我真的试着自己查看并解决这个问题,但是我在XML或网格视图上找到的所有内容或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;

3 个答案:

答案 0 :(得分:0)

您的XML文件不正确。

<NAME2>Doe</NAME3> 

应该是

<NAME2>Doe</NAME2>

答案 1 :(得分:0)

您的foreach循环显然告诉我们遍历每个<ADRESSE>节点,您可以像下列其中一个一样修复它:

//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)

3&amp; 4看起来简直错了。这样,即使它起作用,你也会以多行结束,每列一列,相应的行列填充XML的值,其余列为空。修复1&amp; 2然后你可以专注于3&amp; 4,用最近的尝试编辑问题 - 或者打开新问题 - 如果你不能让它在最后工作。

编辑:

在谷歌上进行快速搜索表明,带有动态列的ListView似乎不是一项简单的任务(一些相关主题:12

您可能想尝试这种方式(根据上面的第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);
....

答案 2 :(得分:0)

我现在只需编写部分解决方案,这将需要比我想要的更多硬编码,但总比没有好 - 也许别人需要它(非常感谢 har07 )< / p>

        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 

这样,在我第一次使用后续ADRESSE标记中的ChildElements的顺序无关紧要(因为需要第一个Parent才能正确创建列)。所以第二个改组的ADRESSE条目如下:

    <?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>

仍将填入正确的列。现在只剩下的问题是第一个条目的Bindings(或列的namings)的依赖性,如果我使用另一种具有不同条目的XML,我必须重命名所有FeldX = xe.Element("XXX").Value中的每个X.

仍然:如果有人知道一个接近的解决方案(我知道这完全被破坏了,但是)像 - &gt;

lv1.Items.Add(new{ string.Format(@"Feld{0}", counter) = xe.Element(@"{0}", xele.Name.LocalName).Value} 

进入循环我真的很感激!