在离开行时,DataGrid会将值恢复为原始值

时间:2013-07-22 19:53:12

标签: wpf mvvm binding datagrid

出于某种原因,当我更新DataGrid中的值时,它们不会保留在内存中对象中?实际上,在编辑单元格期间会显示新值,但只要我切换到下一行,值就会恢复。

这是我的DataGrid定义:

<DataGrid ItemsSource="{Binding Items, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Position X" Binding="{Binding Position.X, Mode=TwoWay}"/>
        <DataGridTextColumn Header="Position Y" Binding="{Binding Position.Y, Mode=TwoWay}"/>
        <DataGridTextColumn Header="Position Z" Binding="{Binding Position.Z, Mode=TwoWay}"/>
        <DataGridTextColumn Header="Rotation" Binding="{Binding Angles[2], Mode=TwoWay}"/>
    </DataGrid.Columns>
</DataGrid>

对象是:

public class Box{
  public Vector3D Position { get; set; }
  public double[] Angles { get; set; }
}

EDIT1

经过进一步检查,我注意到Vector3DSystem.Windows.Media.Media3D)是一个结构,而不是一个类。因此,我怀疑Position.X的间接不起作用。

话虽如此,当我删除了除“{旋转”绑定之外的所有绑定({1}}时,它仍然无效。

EDIT2 :Binding报告的诊断,即绑定停用分离

1 个答案:

答案 0 :(得分:0)

我设法通过创建值转换器将您的Vector3D绑定到DataGridTextColumn

public class StringToStructConverter : IValueConverter
{
    private Vector3D vector3D = new Vector3D();

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        vector3D = (Vector3D)value;
        if (parameter.ToString() == "X") return vector3D.X.ToString();
        else if (parameter.ToString() == "Y") return vector3D.Y.ToString();
        else if (parameter.ToString() == "Z") return vector3D.Z.ToString();
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || value.GetType() != typeof(string) || targetType != typeof(Vector3D)) return false;

        if (parameter.ToString() == "X") vector3D.X = double.Parse(value.ToString());
        else if (parameter.ToString() == "Y") vector3D.Y = double.Parse(value.ToString());
        else if (parameter.ToString() == "Z") vector3D.Z = double.Parse(value.ToString());
        return vector3D;
    }
}

<DataGrid ItemsSource="{Binding DataContext.Items, Mode=TwoWay, ElementName=This}" IsSynchronizedWithCurrentItem="True" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Position X" Binding="{Binding Position, 
Converter={StaticResource StringToStructConverter}, ConverterParameter=X, Mode=TwoWay}"/>
        <DataGridTextColumn Header="Position Y" Binding="{Binding Position, 
Converter={StaticResource StringToStructConverter}, ConverterParameter=Y, Mode=TwoWay}"/>
        <DataGridTextColumn Header="Position Z" Binding="{Binding Position, 
Converter={StaticResource StringToStructConverter}, ConverterParameter=Z, Mode=TwoWay}"/>
        <DataGridTextColumn Header="Rotation" Binding="{Binding Angles[2], Mode=TwoWay}"/>
    </DataGrid.Columns>
</DataGrid>

然而,这种方法并不完美,如果将Vector3D结构更改为具有相同属性的类,则可以省去一大堆麻烦。你甚至可以保留你的结构(我猜你有理由首先选择它),但只是将它转换成一个类只是为了在DataGrid中编辑它然后转换回来?这可以在几毫秒内完成,但可以节省你几个小时的头痛。 :)