将 DataGrid 的 ItemsSource 绑定到列表
Bind the ItemsSource of a DataGrid to a List
我正在尝试在 List
和 DataGrid
之间创建绑定。我还没有在网上找到一个非常奇怪的有效解决方案。
在我的小示例中,我创建了一个 List
对象,其中包含两个 public
属性 Age
和 Name
:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public ObservableCollection<Person> Collection { get; set; }
public List<Person> Persons { get; set; }
private void WindowLoaded(object sender, RoutedEventArgs e)
{
this.Persons = new List<Person>();
for (int i = 0; i != 35; i++)
{
this.Persons.Add(new Person() {Age = i, Name = i.ToString()});
}
this.Collection = new ObservableCollection<Person>(this.Persons);
}
XAML 代码如下所示:
<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
<DataGrid x:Name="DataGrid" ItemsSource="{Binding Collection}" />
</Grid>
或者这个(两者都不工作):
<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
<DataGrid x:Name="DataGrid" ItemsSource="{Binding Persons}" />
</Grid>
如果我使用 this.DataGrid.ItemsSource = this.Persons;
我至少会看到列表中的所有项目,但每次源 List
更改时我都必须 this.DataGrid.Items.Refresh()
这就是我问的原因问题:
我做错了什么?我需要实施 INotifyPropertyChanged
吗?
这个问题一定很容易回答,但如果能理解其中的原理也很棒。
我在 Windows 具有数据网格视图的表单应用程序中经常做类似的事情。所以也许这可以为您指明正确的方向...我对 wpf 没有太多经验。
List<Connection> connList = new List<Connection>();
//populate list somehow
BindingSource bs = new BindingSource();
bs.DataSource = connList;
DataGrid.DataSource = bs;
public class Connection
{
public string Name {get; set;}
public string Connect {get; set;}
public Connection(string n, string c)
{
Name = n;
Connect = c;
}
}
经过漫长的一天编码后,我感到非常紧张和疲倦。解决方案非常简单:
为 Person
class 实施 INotifyPropertyChanged
Interface
:
public class Person: INotifyPropertyChanged
{
private string name;
private int age;
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
this.OnPropertyChanged("Name");
}
}
public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
this.OnPropertyChanged("Age");
}
}
protected void OnPropertyChanged(string name)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
然后将数据与后面的这些代码绑定:
this.DataGrid.DataContext = this.Persons;
要成功 Binding
您还需要这些 XAML
代码:
<DataGrid x:Name="DataGrid" ItemsSource="{Binding}" />
DataGrid
中的值现在会在 Person
实例之一的数据发生变化时刷新。
好的,您遇到问题的原因是加载 window 时发生的情况以及数据绑定的设置方式。
DataGrid 的 ItemsSource 直到 Window 已经加载(它在您的 Window 加载事件中设置)才会发生。因此,DataGrid 现在不会更改 ItemsSource。您可以通过添加更改为列表本身的 INotiftyProperty 来解决此问题,或者,您可以先创建 DataGrid 列表,然后在加载 Window 时填充。
例如:
xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
Collection = new ObservableCollection<Person>();
InitializeComponent();
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public ObservableCollection<Person> Collection { get; set; }
public List<Person> Persons { get; set; }
private void WindowLoaded(object sender, RoutedEventArgs e)
{
this.Persons = new List<Person>();
for (int i = 0; i != 35; i++)
{
this.Persons.Add(new Person() { Age = i, Name = i.ToString() });
}
foreach (var p in Persons)
{
Collection.Add(p);
}
}
}
xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
x:Name="TestWindow"
Loaded="WindowLoaded">
<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
<DataGrid x:Name="DataGrid" ItemsSource="{Binding Collection}" />
</Grid>
</Window>
我正在尝试在 List
和 DataGrid
之间创建绑定。我还没有在网上找到一个非常奇怪的有效解决方案。
在我的小示例中,我创建了一个 List
对象,其中包含两个 public
属性 Age
和 Name
:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public ObservableCollection<Person> Collection { get; set; }
public List<Person> Persons { get; set; }
private void WindowLoaded(object sender, RoutedEventArgs e)
{
this.Persons = new List<Person>();
for (int i = 0; i != 35; i++)
{
this.Persons.Add(new Person() {Age = i, Name = i.ToString()});
}
this.Collection = new ObservableCollection<Person>(this.Persons);
}
XAML 代码如下所示:
<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
<DataGrid x:Name="DataGrid" ItemsSource="{Binding Collection}" />
</Grid>
或者这个(两者都不工作):
<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
<DataGrid x:Name="DataGrid" ItemsSource="{Binding Persons}" />
</Grid>
如果我使用 this.DataGrid.ItemsSource = this.Persons;
我至少会看到列表中的所有项目,但每次源 List
更改时我都必须 this.DataGrid.Items.Refresh()
这就是我问的原因问题:
我做错了什么?我需要实施 INotifyPropertyChanged
吗?
这个问题一定很容易回答,但如果能理解其中的原理也很棒。
我在 Windows 具有数据网格视图的表单应用程序中经常做类似的事情。所以也许这可以为您指明正确的方向...我对 wpf 没有太多经验。
List<Connection> connList = new List<Connection>();
//populate list somehow
BindingSource bs = new BindingSource();
bs.DataSource = connList;
DataGrid.DataSource = bs;
public class Connection
{
public string Name {get; set;}
public string Connect {get; set;}
public Connection(string n, string c)
{
Name = n;
Connect = c;
}
}
经过漫长的一天编码后,我感到非常紧张和疲倦。解决方案非常简单:
为 Person
class 实施 INotifyPropertyChanged
Interface
:
public class Person: INotifyPropertyChanged
{
private string name;
private int age;
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
this.OnPropertyChanged("Name");
}
}
public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
this.OnPropertyChanged("Age");
}
}
protected void OnPropertyChanged(string name)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
然后将数据与后面的这些代码绑定:
this.DataGrid.DataContext = this.Persons;
要成功 Binding
您还需要这些 XAML
代码:
<DataGrid x:Name="DataGrid" ItemsSource="{Binding}" />
DataGrid
中的值现在会在 Person
实例之一的数据发生变化时刷新。
好的,您遇到问题的原因是加载 window 时发生的情况以及数据绑定的设置方式。
DataGrid 的 ItemsSource 直到 Window 已经加载(它在您的 Window 加载事件中设置)才会发生。因此,DataGrid 现在不会更改 ItemsSource。您可以通过添加更改为列表本身的 INotiftyProperty 来解决此问题,或者,您可以先创建 DataGrid 列表,然后在加载 Window 时填充。
例如:
xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
Collection = new ObservableCollection<Person>();
InitializeComponent();
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public ObservableCollection<Person> Collection { get; set; }
public List<Person> Persons { get; set; }
private void WindowLoaded(object sender, RoutedEventArgs e)
{
this.Persons = new List<Person>();
for (int i = 0; i != 35; i++)
{
this.Persons.Add(new Person() { Age = i, Name = i.ToString() });
}
foreach (var p in Persons)
{
Collection.Add(p);
}
}
}
xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
x:Name="TestWindow"
Loaded="WindowLoaded">
<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
<DataGrid x:Name="DataGrid" ItemsSource="{Binding Collection}" />
</Grid>
</Window>