将 DataGrid 的 ItemsSource 绑定到列表

Bind the ItemsSource of a DataGrid to a List

我正在尝试在 ListDataGrid 之间创建绑定。我还没有在网上找到一个非常奇怪的有效解决方案。

在我的小示例中,我创建了一个 List 对象,其中包含两个 public 属性 AgeName:

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>