繁体   English   中英

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

[英]Binding an observable collection to a 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;
        }
    }
}

更改datagrid代码,因为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>

值得庆幸的是,有一些事情使您的示例无法正常工作,大部分都是小小的调整。

首先要注意的是,通常,您应该始终绑定到public Properties ,而不是当前正在绑定的字段。

因此,您所需的绑定属性应变为:

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

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

(请注意,我已使属性以大写字母开头,这通常是公共属性的良好做法。此站点上已经存在许多出色的解释,而其他人则提供有关此主题的更多信息。

另外,当您分配DataContext ,然后初始化属性personsInformation ,您实际上是在不通知UI的情况下更改personsInformation字段-此更改将不会被使用,并且对新集合的任何其他更改(或属性的分配)本身),则不会反映在用户界面中。

在此阶段,最简单的解决方法是在this.DataContext = this;行之前的某个点简单地初始化personsInformation this.DataContext = this; 例如:

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应该可以按.firstName工作,但。可以。 不需要。 我倾向于写诸如{Binding Path=firstName}类的{Binding Path=firstName} ,这纯粹是一种样式首选项(它对我来说很清楚),您可以像完成{Binding firstName}一样省略路径。 但这应该可以启动并运行您的示例,并允许您进行一些有趣的探索/测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM