Создайте пользовательский источник данных DataGrid - не работает

Я пытаюсь воспроизвести решение из Create Custom DataGrid ItemsSource, но мои строки не заселение.

Столбцы отображаются с правильными заголовками, но в сетке нет данных.

Может ли кто-нибудь сказать мне, что я делаю неправильно?

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

Мне кажется, что я так близок к этому, но я просто упускаю одну вещь.
Возможно, контекст данных неверен?


person Grant McConville    schedule 20.05.2017    source источник
comment
Имена свойств чувствительны к регистру. Попробуйте изменить MyId на MyID в привязке. В окне вывода должна быть ошибка привязки.   -  person Yevgeniy    schedule 21.05.2017
comment
Что сказал Евгений. Но, кроме того, еще одна важная вещь заключается в том, что привязка к вашей коллекции (myList) не получает информации о том, что значение этого свойства было изменено (т. е. вы присвоили этому свойству объект ObservableCollection). Следовательно, вы не видите никакого эффекта.   -  person    schedule 21.05.2017
comment
Я предлагаю вам создать класс ViewModel, в котором вы объявляете и инициализируете свойство ObservableCollection. Используйте класс ViewModel в качестве DataContext. Реализуйте интерфейс INotifyPropertyChanged для класса ViewModel. В установщике для всех свойств в ViewModel запустите событие PropertyChanged. Таким образом, привязки будут информироваться всякий раз, когда свойство, к которому они привязаны, изменяется...   -  person    schedule 21.05.2017


Ответы (2)


когда вы назначаете DataContext, myList равно null. Когда оно создается позже, свойство не сообщает об изменении (через событие)

быстрое исправление - изменить порядок операций:

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), поскольку путь привязки должен соответствовать имени свойства

но я предлагаю создать отдельный класс (который реализует INotifyPropertyChanged) со свойством myList и использовать экземпляр этого класса (модель представления) для установки DataContext окна.

person ASh    schedule 21.05.2017
comment
Я изменил свой код и думаю, что близок к тому, чтобы заставить его работать - person Grant McConville; 29.05.2017

Догадаться.

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>
person Grant McConville    schedule 31.05.2017