创建自定义 DataGrid 的 ItemsSource - 不工作

Create a custom DataGrid's ItemsSource - not working

我正在尝试从 Create a custom DataGrid's ItemsSource 复制解决方案,但我的行没有填充。

列显示正确 headers,但网格中没有数据。

谁能告诉我我做错了什么?

using System;
using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;

namespace WPFBindingDataGridTest2
{
    public partial class MainWindow : Window
    {
        public ObservableCollection<MyObject> myList { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            testClass = new ObservableCollection<TestClass>();
            testClass.Add(new TestClass(NameValue: "John"));
            testClass.Add(new TestClass(NameValue: "Frank"));
            testClass.Add(new TestClass(NameValue: "Sarah"));
            testClass.Add(new TestClass(NameValue: "David"));
        }
    }

    class TestClass : INotifyPropertyChanged
    {
        private string name;

        public TestClass(string NameValue)
        {
            this.Name = NameValue;
        }

        public String Name
        {
            get { return name; }
            set { this.name = value; NotifyPropertyChanged(); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

还有 XAML...

<Grid>
    <DataGrid x:Name="dataGrid" ItemsSource="{Binding testClass}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

我得到的错误是

System.Windows.Data Error: 40 :  
BindingExpression path error:  
'testClass' property not found on 'object'''MainWindow' 
(Name='')'.BindingExpression:  
Path=testClass;  
DataItem='MainWindow' (Name='');  
target element is 'DataGrid' (Name='dataGrid');  
target property is 'ItemsSource' (type 'IEnumerable')

我觉得我离这个很近了,但我只是错过了一件事。
可能是数据上下文错误?

当您分配 DataContext 时,myListnull。稍后创建时,属性 不会报告更改(通过事件)

快速修复是更改操作顺序:

public MainWindow()
{
    myList = new ObservableCollection<MyObject>
    {
      new MyObject() { MyID = "6222" },
      new MyObject() { MyID = "12" },
      new MyObject() { MyID = "666" }
    };
    this.DataContext = this;
    InitializeComponent();
}

还修复了列绑定 (Binding="{Binding MyID}") 或 属性 名称 (MyId),因为绑定路径应匹配 属性 名称

但我建议使用 myList 属性 创建一个单独的 class(实现 INotifyPropertyChanged),并使用 class 的一个实例(查看模型)以设置 window 的 DataContext

想通了。

using System;
using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;

namespace WPFBindingDataGridTest2
{
    public partial class MainWindow : Window
    {
        private ObservableCollection<TestClass> testClass;

        public MainWindow()
        {
            InitializeComponent();

            testClass = new ObservableCollection<TestClass>();
            testClass.Add(new TestClass(NameValue: "John"));
            testClass.Add(new TestClass(NameValue: "Frank"));
            testClass.Add(new TestClass(NameValue: "Sarah"));
            testClass.Add(new TestClass(NameValue: "David"));

            // this.DataContext = this does not appear to be nessecary if it the class is stored in the main window
            dataGrid.ItemsSource = testClass;

        }
    }

    class TestClass : INotifyPropertyChanged
    {
        private string name;

        public TestClass(string NameValue)
        {
            this.Name = NameValue;
        }

        public String Name
        {
            get { return name; }
            set { this.name = value; NotifyPropertyChanged(); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

XAML

<Window x:Class="WPFBindingDataGridTest2.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"
        xmlns:local="clr-namespace:WPFBindingDataGridTest2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid x:Name="dataGrid" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>