I have this simple DataGrid in my application. Somewhere in the source I bind the ItemsSource
property of it to an ObservableCollection<System.Windows.Points>
. So the points are shown in the DataGrid
. The problem is however I have set the TwoWay
binding but when changing the point coordinate values in the DataGrid
, actual point values int the ObservableCollection
are not changed!
What is going wrong?
<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>
Note I have seen this but my problem is different.
System.Windows.Points
is a struct. You can't bind its properties correctly.
Why? Because when you do Text="{Binding X, Mode=TwoWay}"
it will bind the Text
property of the TextBox
to the X
property of the current DataContext
.
DataContext
which is... a struct System.Windows.Points
then the Point
the databinding will modify is not the one you have assigned to DataContext
.
To solve your problem. Create your own Point
type using a class:
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));
}
}
and use UpdateSourceTrigger=LostFocus
for your binding:
<TextBox Text="{Binding Path=Y, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"></TextBox>