【问题标题】:DataGrid reverts the values back to original when leaving row离开行时,DataGrid 将值恢复为原始值
【发布时间】:2013-07-21 16:45:50
【问题描述】:

由于某种原因,当我更新 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 的间接寻址不起作用。

话虽如此,当我删除了“旋转”绑定(double[])之外的所有内容时,它仍然不起作用。

EDIT2:Binding 诊断报告表明该绑定停用分离

【问题讨论】:

  • 显示 Vector3D 类/结构
  • @Blam,这是.NET class
  • @NewDev,你需要提交编辑
  • @Blam,实际上,Vector3D 事实证明,它不是 class,而是 struct... 我怀疑它可能是罪魁祸首 - 请参阅更新后的问题

标签: wpf mvvm binding datagrid


【解决方案1】:

我设法通过创建值转换器将您的 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 中编辑它,然后再转换回来?这可以在几毫秒内完成,但可以为您节省数小时的头痛。 :)

【讨论】:

  • 是的,这个值转换器不能正确“转换回来”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多