wpf 将 DataGrid 的 ItemsSource 绑定到列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32257785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:22:27  来源:igfitidea点击:

Bind the ItemsSource of a DataGrid to a List

c#wpfbindingdatagrid

提问by Jens

I am trying to create a binding between a Listand a DataGrid. I haven't found a working Solution in the net which is very strange.

我正在尝试在 aList和 a之间创建绑定DataGrid。我还没有在网上找到有效的解决方案,这很奇怪。

In my little example I create a Listof objects with the two publicproperties Ageand Name:

在我的小例子中,我创建了一个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);
}

The XAML Code looks like this:

XAML 代码如下所示:

<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
    <DataGrid x:Name="DataGrid" ItemsSource="{Binding Collection}" />
</Grid>

or this (both is not working):

或者这个(两者都不起作用):

<Grid DataContext="{Binding ElementName=TestWindow, Path=.}">
        <DataGrid x:Name="DataGrid" ItemsSource="{Binding Persons}" />
</Grid>

if I use this.DataGrid.ItemsSource = this.Persons;I see at least all the items in the list but I have to this.DataGrid.Items.Refresh()every time the Source Listchanges which is the reason why I ask the question:

如果我使用,this.DataGrid.ItemsSource = this.Persons;我至少会看到列表中的所有项目,但this.DataGrid.Items.Refresh()每次 SourceList更改时我都必须查看,这就是我提出问题的原因:

What am I doing wrong? Do I need to implement INotifyPropertyChanged?

我究竟做错了什么?我需要实施INotifyPropertyChanged吗?

This question must be very easy to answer but it would be also awesome to understand the mechanics.

这个问题一定很容易回答,但理解机制也会很棒。

回答by d.moncada

Okay, so the reason why you are having issues is because what happens when the window is loaded and how the data binding is set up.

好的,所以您遇到问题的原因是因为加载窗口时会发生什么以及如何设置数据绑定。

The ItemsSource of the DataGrid doesn't happen until the Window has already loaded (it's getting set in your Window loaded event). So as a result, the DataGrid does not now that it's ItemsSource has changed. You can fix this by adding INotiftyProperty changed to the list itself, or, you can create the DataGrid list first, and just populate when the Window has loaded.

DataGrid 的 ItemsSource 不会发生,直到 Window 已经加载(它在您的 Window 加载事件中设置)。因此,DataGrid 现在不会因为它的 ItemsSource 已经改变。您可以通过将 INotiftyProperty 更改添加到列表本身来解决此问题,或者,您可以先创建 DataGrid 列表,然后在窗口加载时填充。

For example:

例如:

xaml.cs

xml文件

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:

xml:

<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>

回答by Jens

After a very long day of coding I was too nervous and tired. the solution is very easy:

经过一整天的编码后,我太紧张了,太累了。解决方案很简单:

Implement the INotifyPropertyChangedInterfacefor the Personclass:

实现INotifyPropertyChangedInterfacePerson类:

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;
}

And then bind the Data with these Code behind:

然后将数据与后面的这些代码绑定:

this.DataGrid.DataContext = this.Persons;

For a successful Bindingyou need also these XAMLCode:

为了成功,Binding您还需要这些XAML代码:

<DataGrid x:Name="DataGrid" ItemsSource="{Binding}" />

The valuesin the DataGridwill now refresh whenever the Data in one of the Personinstances changes.

DataGrid现在,只要Person实例之一中的数据发生变化,其中的值就会刷新。

回答by scubasteve623

I do a similar thing a ton in Windows Forms Apps with data grid views. So maybe this can point you in the right direction... I don't have much experience with wpf.

我在带有数据网格视图的 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;
        }
    }