如何将 List<CustomObject> 绑定到 WPF DataGrid?

Posted

技术标签:

【中文标题】如何将 List<CustomObject> 绑定到 WPF DataGrid?【英文标题】:How do I bind a List<CustomObject> to a 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 中进行操作?

【问题讨论】:

【参考方案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_Testget;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 异常

以上是关于如何将 List<CustomObject> 绑定到 WPF DataGrid?的主要内容,如果未能解决你的问题,请参考以下文章

接受 List<CustomObject> 的 ASP.NET Web 方法因“Web 服务方法名称无效”而失败。

将 Set<CustomObject> 存储到 UserDefaults

LINQ 分组为字典对象

如何线程安全存档一组自定义对象?

<UUID,CustomObject>的Java排序图[重复]

从 JSONArray 转换为 ArrayList<CustomObject> - Android