TwoWay Binding ObservableCollection для DataGrid в WPF не работает

У меня есть этот простой DataGrid в моем приложении. Где-то в исходном коде я связываю его свойство ItemsSource с ObservableCollection<System.Windows.Points>. Таким образом, точки показаны в DataGrid. Однако проблема в том, что я установил привязку TwoWay, но при изменении значений координат точки в DataGrid фактические значения точек в ObservableCollection не изменяются!

Что происходит не так?

<DataGrid Name="pointList" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="X" Width="200">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Path=X, Mode=TwoWay}"></TextBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Y" Width="200">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Path=Y, Mode=TwoWay}"></TextBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Примечание Я видел это, но мой проблема в другом.


person Hossein Narimani Rad    schedule 30.01.2013    source источник
comment
Опять же: наблюдаемая коллекция не имеет ничего общего с хранящимися в ней данными. System.Windows.Point - это структура. Вы не можете использовать его для этого. Создайте ViewModel.   -  person Federico Berasategui    schedule 30.01.2013


Ответы (1)


System.Windows.Points – это структура. Вы не можете правильно связать его свойства.

Почему? Потому что, когда вы делаете Text="{Binding X, Mode=TwoWay}", свойство Text TextBox привязывается к свойству X текущего DataContext.

DataContext, который является... структурой System.Windows.Points, тогда Point, который будет изменен привязкой данных, не тот, который вы назначили DataContext.

Чтобы решить вашу проблему. Создайте свой собственный тип Point с помощью класса:

public class Point : INotifyPropertyChanged
{
    private double x;
    public double X
    {
        get { return x; }
        set
        {
            if (x != value)
            {
                x = value;
                OnPropertyChanged("X");
            }
        }
    }
    private double y;
    public double Y
    {
        get { return y; }
        set
        {
            if (y != value)
            {
                y = value;
                OnPropertyChanged("Y");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

и используйте UpdateSourceTrigger=LostFocus для привязки:

<TextBox Text="{Binding Path=Y, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"></TextBox>
person Cédric Bignon    schedule 30.01.2013
comment
Я использую этот класс, но ничего не изменилось! Не обновляются баллы! не должен ли я внести некоторые изменения в мой DataGrid. Какое событие следует использовать при редактировании ячеек? - person Hossein Narimani Rad; 30.01.2013
comment
@HosseinNarimaniRad Итак, теперь ItemsSource привязан к ObservableCollection‹YourNamespace.Points›, и он все еще не работает? - person Cédric Bignon; 30.01.2013
comment
Вот код: this.dataGrid.ItemsSource = this.points; точек — это ObservableCollection‹MyNamespace.Points›. и это не работает. - person Hossein Narimani Rad; 30.01.2013
comment
Пробовал сделать привязку с кодом. но там написано что Two-way binding requires Path or XPath. - person Hossein Narimani Rad; 30.01.2013
comment
@HosseinNarimaniRad Я нашел проблему. Посмотрите в конце моего поста. - person Cédric Bignon; 30.01.2013