将可观察集合绑定到数据网格?

时间:2015-06-07 14:34:11

标签: c# wpf datagrid

最近我一直在努力学习WPF,试图学习WPF我一直在创建一个小小的项目来熟悉WPF。目前,我目前在WPF中遇到绑定问题。更具体地说,将可观察集合绑定到数据网格。你可以在下面看到我的代码

<Window x:Class="Progress_bar_example.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid AutoGenerateColumns="False" Height="287" HorizontalAlignment="Left"
            Margin="20,12,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="471"
            ItemsSource="{Binding personsInformation}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="First Name" Binding="{Binding .firstName}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

,后端代码为

namespace Progress_bar_example
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public class myDataContext
        {
            private ObservableCollection<PersonData> personsInformation;
        }

        public class PersonData
        {
            public String firstName;
            //public String sureName;
            //public int dayOfBirth;
            //public int monthOfBirth;
            //public int yearOfBirth;
        }

        public ObservableCollection<PersonData> personsInformation;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            personsInformation = new ObservableCollection<PersonData>();
            PersonData person = new PersonData() 
            { 
                firstName = "Thomas"
            };
            personsInformation.Add(person);

            ContentRendered += Window_ContentRendered;
        }

        private void Window_ContentRendered(object sender, EventArgs e)
        {            
            //this.DataContext = _dt;
        }
    }
}

2 个答案:

答案 0 :(得分:0)

更改数据网格代码,因为datagridtextcolumn列名不应与Dot(。)绑定

<DataGrid AutoGenerateColumns="False" Height="287" HorizontalAlignment="Left" Margin="20,12,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="471" ItemsSource="{Binding personsInformation}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="First Name" Binding="{Binding firstName}"/>
    </DataGrid.Columns>
</DataGrid>

答案 1 :(得分:0)

有一些事情阻止你的例子正常工作,谢天谢地,大多数都是小调整。

首先要注意的是,一般来说,你应该始终绑定到公共Properties,而不是你现在正在做的字段。

所以你想要的绑定属性应该成为:

// More Code
public ObservableCollection<PersonData> PersonsInformation { get; set; }

public class PersonData
{
    public String FirstName { get; set; }
    // More Code
}

(注意我已经使大写字母以大写字母开头,这通常是公共属性的好习惯。 本网站上已有许多出色的解释,其他有关此主题的更多信息。

此外,当您分配DataContext,然后初始化属性personsInformation时,您实际上是在更改personsInformation字段而不通知用户界面 - 此更改将不会被选中,对新集合的任何进一步更改(或属性本身的分配)都不会反映在用户界面中。

此阶段最简单的解决方法是在行personsInformation之前的某个位置简单地初始化this.DataContext = this; e.g:

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    personsInformation = new ObservableCollection<PersonData>();

    this.DataContext = this;
    // Code that modifies personsInformation.
}

注意:绑定到集合(特别是ObservableCollection)的错误的一个相当常见的原因是在分配持有集合的Property和修改该集合之间的区别。 ObservableCollection本身实现了INotifyPropertyChanged,它在添加/删除/清除项目时提供通知。如果您为personsInformation分配了新的收藏集,则不会发出任何通知(除非您已实施INotifyPropertyChanged并提出了相应的通知(有关该主题的大量优秀指南)。

您还可以考虑其他事项,例如将DataContext分配到其他地方,涉及ViewModels,实现iNotifyPropertyChanged。

此外,绑定到.firstName应该按照您的意图工作,但是。不需要。我倾向于编写像{Binding Path=firstName}这样的绑定,这纯粹是一种风格偏好(它清楚地告诉我),你可以像你所做的那样省略路径{Binding firstName}。 但这应该让你的例子开始运行,让你继续进行一些有趣的探索/测试。