【问题标题】:How do I bind a List<CustomObject> to a WPF DataGrid?如何将 List<CustomObject> 绑定到 WPF DataGrid?
【发布时间】:2011-06-26 10:02:38
【问题描述】:

我是 WPF 新手,想做一些基本的数据绑定。 我有一个 CustomObject 列表,想将它绑定到 DataGrid。

MainWindow.xaml.cs

   using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace WpfApplication1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                List<ArticleItem> list = new List<ArticleItem>() 
                {
                new ArticleItem(){ ID=3, Title="test", ViewCount=5},
                new ArticleItem(){ ID=3, Title="test", ViewCount=5},
                new ArticleItem(){ ID=3, Title="test", ViewCount=5},
                new ArticleItem(){ ID=3, Title="test", ViewCount=5},
                };
            }
        }

        public class ArticleItem 
        {
            public int ID { get; set; }
            public int ViewCount { get; set; }
            public String Title { get; set; }
        }
    }

这是我的网格的样子:

<DataGrid Height="179" HorizontalAlignment="Left" Margin="54,65,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="382">
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID"/>
            <DataGridTextColumn Header="ViewCount" />
        <DataGridTextColumn Header="Title" />
    </DataGrid.Columns>
</DataGrid>

我习惯了 ASP.Net 的数据绑定,在这里我可以很容易地说:

this.dataGrid1.DataSource = list;

我必须如何在 WPF 中进行操作?

【问题讨论】:

    标签: c# wpf data-binding datagrid


    【解决方案1】:

    您应该在 xaml 代码中执行此操作:

    <DataGrid ItemsSource="{Binding list}" [...]>
      [...]
    </DataGrid>
    

    我建议您使用 ObservableCollection 作为支持集合,因为这会将更改传播到数据网格,因为它实现了 INotifyCollectionChanged

    【讨论】:

    • 我不明白。我开始列出一个实例变量,并为 DataGrid 使用了这个 xaml 属性:ItemsSource="{Binding list}" AutoGenerateColumns="true"。出现异常时,我看到一个空的 DataGrid,没有行也没有列
    • 它必须是数据绑定的属性。另外,查看输出窗口,通常会有一些信息可以帮助您找出问题所在。
    • @citronas:除了使 List 成为属性之外,DataGrid 还需要有一个 DataContext 才能使 Binding 工作。在MainWindow 的构造函数中设置this.DataContext = this;,它应该可以工作
    • @Meleak,永远不要在控件构造函数中设置 self DataContext!你最好学习 OP 使用RelativeSource 绑定属性。
    • 这是一个更好的答案,接受的答案将功能无法与数据网格很好地同步。当发生更改时,您需要手动调用dataGrid.Items.Refersh(),并且该调用不会通过单击列进行过滤。使用ObservableCollection 可以解决所有这些问题。
    【解决方案2】:

    如果您不希望重新创建您的 list,那么您可以使用与用于 Asp.Net 相同的方法(而不是 DataSource,WPF 中的此属性通常命名为 ItemsSource):

    this.dataGrid1.ItemsSource = list;
    

    但如果您想用新的集合实例替换您的list,那么您应该考虑使用databinding

    【讨论】:

    • 我在 DataGrid 中有多个行,其中每个 datagrid 行都有一个按钮,单击它会打开一个弹出窗口,在弹出窗口中我有另一个带按钮的数据网格,现在我想要这个按钮的 Onclick获取单击按钮的相应行数据,并将此行数据添加到打开弹出窗口的第一个 dataGrid Row。
    【解决方案3】:

    实际上,要正确支持排序、过滤等,应该使用 CollectionViewSource 作为 DataGrid 和列表之间的链接,如下所示:

    <Window.Resources>
      <CollectionViewSource x:Key="ItemCollectionViewSource" CollectionViewType="ListCollectionView"/>
    </Window.Resources>   
    

    DataGrid 行如下所示:

    <DataGrid
      DataContext="{StaticResource ItemCollectionViewSource}"
      ItemsSource="{Binding}"
      AutoGenerateColumns="False">  
    

    在后面的代码中,您将 CollectionViewSource 与您的链接链接起来。

    CollectionViewSource itemCollectionViewSource;
    itemCollectionViewSource = (CollectionViewSource)(FindResource("ItemCollectionViewSource"));
    itemCollectionViewSource.Source = itemList;
    

    有关详细示例,请参阅我关于 CoedProject 的文章: http://www.codeproject.com/Articles/683429/Guide-to-WPF-DataGrid-formatting-using-bindings

    【讨论】:

    • 喜欢这种方法 - 在过去几年中,您是否以可重用的方式对其进行了改进?
    • 我不确定您所说的“可重用方式”是什么意思。顺便说一句,当您将表从“数据源”窗口拖放到 WPF 窗口时,Visual Studio 会生成类似的代码。
    【解决方案4】:

    您不需要在 xaml 中手动指定列名。只需将 AutoGenerateColumns 属性设置为 true,您的列表就会自动绑定到 DataGrid。参考代码。 XAML 代码:

    <Grid>
        <DataGrid x:Name="MyDatagrid" AutoGenerateColumns="True" Height="447" HorizontalAlignment="Left" Margin="20,85,0,0" VerticalAlignment="Top" Width="799"  ItemsSource="{Binding Path=ListTest, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  CanUserAddRows="False"> </Grid>
    

    C#

    Public Class Test 
    {
        public string m_field1_Test{get;set;}
        public string m_field2_Test { get; set; }
        public Test()
        {
            m_field1_Test = "field1";
            m_field2_Test = "field2";
        }
        public MainWindow()
        {
    
            listTest = new List<Test>();
    
            for (int i = 0; i < 10; i++)
            {
                obj = new Test();
                listTest.Add(obj);
    
            }
    
            this.MyDatagrid.ItemsSource = ListTest;
    
            InitializeComponent();
    
        }
    

    【讨论】:

    • 谢谢。最初我没有getset,这意味着什么都没有生成,我很困惑。
    • this.MyDatagrid.XXX 将在 InitalizeComponent() 之前 nullref 异常
    猜你喜欢
    • 2015-09-02
    • 2011-02-21
    • 1970-01-01
    • 2017-05-13
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多