none
datagrid 绑定 xml (WPF) RRS feed

  • 问题

  • test.xml 文件的结构为
    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <tt>
      <Album Title="Chris Sells Live" Artist="Chris Sells" ReleaseDate="2/5/2008" >
      <cc>c1</cc>
      <cc>c2</cc>
      </Album>

      <Album Title="The Road to Redmond" Artist="Luka Abrus" ReleaseDate="4/3/2008" />

      <Album Title="The Best of Jim Hance" Artist="Jim Hance" ReleaseDate="6/2/2008" />
      </tt>
      <tt>
      <Album Title="1111" Artist="Chris Sells" ReleaseDate="2/5/2008" />

      <Album Title="2222" Artist="Luka Abrus" ReleaseDate="4/3/2008" />

      <Album Title="3333" Artist="Jim Hance" ReleaseDate="6/2/2008" />
      </tt>
    </root>

    xaml文件的代码如下

    <DataGrid AutoGenerateColumns="False" Height="117" HorizontalAlignment="Left" Margin="14,120,0,0" Name="dataGrid2" VerticalAlignment="Top" Width="246" >
       
      <DataGrid.Columns>
      <DataGridTextColumn Header="test" Binding="{Binding Path=Attribute[Title].Value}"/>
      <DataGridTextColumn Header="test1" Binding="{Binding Path=Elements[cc]}"/>
      </DataGrid.Columns> 
      </DataGrid>

    CS后台的代码如下
      public partial class MainWindow : Window
      {
      public MainWindow()
      {
      InitializeComponent();
      XElement x = XElement.Load(@"D:\C#Wpf\WpfApplication16\WpfApplication16\test.xml");
      this.dataGrid2.ItemsSource = x.Elements("tt").First().Elements();  
      }
      }
    现在test列可以显示数据,可是test1不能够读出数据

    其实我的问题在于,我想把大范围的数据源集合绑定到datagrid上。然后生成列的数据是需要重新整理根据需要在生成列
    2011年1月19日 8:00

答案

  • 你好,

    我看了这个xml数据源,由于WPF的DataGrid没有办法来很好的根据一个动态变化的数据源来动态生成列。所以我们不能单单使用绑定来生成列。对于你的这个需求,我想,只有通过一些代码来把XML数据先格式化成DataTable,然后再直接绑定到DataGrid上。具体代码如下:

          XElement x = XElement.Load(@"data.xml");
    
          DataTable dt = new DataTable();
          dt.Columns.Add(new DataColumn("时间段"));
          foreach (var element in x.Element("PalyTime").Elements())
          {
            DataRow dr = dt.NewRow();
            dr[0] = element.Attribute("time").Value;
            dt.Rows.Add(dr);
          }
          var elements = x.Elements();
          for (int i =0; i<elements.Count();i++)
          {
            dt.Columns.Add(new DataColumn(elements.ElementAt(i).Attribute("date").Value));
            var timeelements = elements.ElementAt(i).Elements();
            for (int j =0; j<timeelements.Count();j++)
            {
              dt.Rows[j][i + 1] = timeelements.ElementAt(j).Value;
            }
          }
    
          this.datagrid.ItemsSource = dt.DefaultView;  
    
    Sincerely,
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年1月23日 15:29
    版主

全部回复

  • 你好,

    Elements 在XElement中是一个方法返回所有符合的Elements,所以返回的是一个集合,我们是不能简单地把一个集合放到一个Cell里面的。而把代码改成:

    <DataGridTextColumn Header="test1" Binding="{Binding Path=Element[cc]}"/>
    

    则只会返回第一个cc元素了。

    所以,考虑到你的需求,并不推荐你使用XElement作为数据源;而是推荐你使用XmlDataProvider来进行控制:

      <Window.Resources>
        <XmlDataProvider x:Key="xmldata" Source="test1.xml" XPath="root/tt[1]/Album"/>
      </Window.Resources>
      <Grid>
        <DataGrid ItemsSource="{Binding Source={StaticResource xmldata}}" AutoGenerateColumns="False" Height="259" HorizontalAlignment="Left" Margin="14,25,0,0" Name="dataGrid2" VerticalAlignment="Top" Width="429" >
          <DataGrid.Columns>
            <DataGridTextColumn Header="test" Binding="{Binding XPath=@Title}"/>
            <DataGridTextColumn Header="test1" Binding="{Binding XPath=cc}"/>
          </DataGrid.Columns>
        </DataGrid>
      </Grid>
    

    相关的资料:

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年1月20日 11:08
    版主
  • 你好,

    Elements 在XElement中是一个方法返回所有符合的Elements,所以返回的是一个集合,我们是不能简单地把一个集合放到一个Cell里面的。而把代码改成:

    <DataGridTextColumn Header="test1" Binding="{Binding Path=Element[cc]}"/>
    

    则只会返回第一个cc元素了。

    所以,考虑到你的需求,并不推荐你使用XElement作为数据源;而是推荐你使用XmlDataProvider来进行控制:

     <Window.Resources>
      <XmlDataProvider x:Key="xmldata" Source="test1.xml" XPath="root/tt[1]/Album"/>
     </Window.Resources>
     <Grid>
      <DataGrid ItemsSource="{Binding Source={StaticResource xmldata}}" AutoGenerateColumns="False" Height="259" HorizontalAlignment="Left" Margin="14,25,0,0" Name="dataGrid2" VerticalAlignment="Top" Width="429" >
       <DataGrid.Columns>
        <DataGridTextColumn Header="test" Binding="{Binding XPath=@Title}"/>
        <DataGridTextColumn Header="test1" Binding="{Binding XPath=cc}"/>
       </DataGrid.Columns>
      </DataGrid>
     </Grid>
    

    相关的资料:

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    非常感谢你的回复,但是我试用你提供的方法还是不行。我在详细的把我的问题叙述一下。以前我的程序是在winform下实现的。 XML文件结构如下: <Task Nid="1" name="12121" StartDate="2010年10月26日" EndDate="2010年10月28日" stime="1:00" etime="5:00"> <PalyTime date="2010年10月26日"> <times time="1:00">模板1</times> <times time="2:00">模板1</times> <times time="3:00"></times> <times time="4:00"></times> <times time="5:00">模板2</times> </PalyTime> <PalyTime date="2010年10月27日"> <times time="1:00">模板2</times> <times time="2:00"></times> <times time="3:00">模板2</times> <times time="4:00">模板1</times> <times time="5:00"></times> </PalyTime> </Task> 这是一个任务,以前我根据这个任务生成在datagrid里的样子为如下的图片所示: <image>http://221.207.220.189/111.png</image> 可以直接访问地址看到图片 现在我要把项目迁移到wpf的项目上。可是多种方法都测试过,包括你提到的XmlDataProvider我也试过。可是仍然达不到我的要求 我在怀疑,wpf项目里的datagrid的是否能生成我在winfrom下datagrid所生成的效果
    2011年1月21日 2:46
  • 你好,

    我看了这个xml数据源,由于WPF的DataGrid没有办法来很好的根据一个动态变化的数据源来动态生成列。所以我们不能单单使用绑定来生成列。对于你的这个需求,我想,只有通过一些代码来把XML数据先格式化成DataTable,然后再直接绑定到DataGrid上。具体代码如下:

          XElement x = XElement.Load(@"data.xml");
    
          DataTable dt = new DataTable();
          dt.Columns.Add(new DataColumn("时间段"));
          foreach (var element in x.Element("PalyTime").Elements())
          {
            DataRow dr = dt.NewRow();
            dr[0] = element.Attribute("time").Value;
            dt.Rows.Add(dr);
          }
          var elements = x.Elements();
          for (int i =0; i<elements.Count();i++)
          {
            dt.Columns.Add(new DataColumn(elements.ElementAt(i).Attribute("date").Value));
            var timeelements = elements.ElementAt(i).Elements();
            for (int j =0; j<timeelements.Count();j++)
            {
              dt.Rows[j][i + 1] = timeelements.ElementAt(j).Value;
            }
          }
    
          this.datagrid.ItemsSource = dt.DefaultView;  
    
    Sincerely,
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年1月23日 15:29
    版主
  • 你好,

    我看了这个xml数据源,由于WPF的DataGrid没有办法来很好的根据一个动态变化的数据源来动态生成列。所以我们不能单单使用绑定来生成列。对于你的这个需求,我想,只有通过一些代码来把XML数据先格式化成DataTable,然后再直接绑定到DataGrid上。具体代码如下:

       XElement x = XElement.Load(@"data.xml");
    
    
    
       DataTable dt = new DataTable();
    
       dt.Columns.Add(new DataColumn("时间段"));
    
       foreach (var element in x.Element("PalyTime").Elements())
    
       {
    
        DataRow dr = dt.NewRow();
    
        dr[0] = element.Attribute("time").Value;
    
        dt.Rows.Add(dr);
    
       }
    
       var elements = x.Elements();
    
       for (int i =0; i<elements.Count();i++)
    
       {
    
        dt.Columns.Add(new DataColumn(elements.ElementAt(i).Attribute("date").Value));
    
        var timeelements = elements.ElementAt(i).Elements();
    
        for (int j =0; j<timeelements.Count();j++)
    
        {
    
         dt.Rows[j][i + 1] = timeelements.ElementAt(j).Value;
    
        }
    
       }
    
    
    
       this.datagrid.ItemsSource = dt.DefaultView; 
    
    
    Sincerely,
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    非常感谢BOB BAO的回复,这个问题终于解决了。看来绑定是有局限的。要不我想我研究那么久了。怎么就解决不了呢。现在终于有解决办法了。在此感谢你的回复,以后有人在遇到这样的问题,也有了答案了
    2011年1月24日 3:10