wpfxamldata-bindingdatagriditemsource

Create a custom DataGrid's ItemsSource - not working


I am trying to replicate the solution from Create a custom DataGrid's ItemsSource but my rows are not populating.

The columns appears with the correct headers, but no data in the grid.

Can anyone please tell me what I am doing wrong?

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

And the XAML...

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

The error I am getting is

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

I feel like I am so close to this, but am just missing one thing.
Possible the data context is wrong?


Solution

  • when you assign DataContext, myList is null. When it is created later, property doesn't report about changing (via event)

    quick fix is to change the order of operations:

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

    also fix column binding (Binding="{Binding MyID}") or property name (MyId) because binding path should match property name

    but I suggest to create a separate class (which implements INotifyPropertyChanged) with myList property, and use an instance of that class (view model) to set DataContext of a window.