[英]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.