gpt4 book ai didi

wpf - 如何在不复制代码的情况下在 WPF 中编辑不可变对象(immutable对象)?

转载 作者:行者123 更新时间:2023-12-04 01:08:48 24 4
gpt4 key购买 nike

我们的领域模型中有很多不可变的值对象,其中一个例子是位置,由纬度、经度和高度定义。

/// <remarks>When I grow up I want to be an F# record.</remarks>
public class Position
{
public double Latitude
{
get;
private set;
}

// snip

public Position(double latitude, double longitude, double height)
{
Latitude = latitude;
// snip
}
}

允许编辑位置的明显方法是构建一个具有 getter 和 setter 的 ViewModel,以及一个 ToPosition() 方法来提取经过验证的不可变位置实例。虽然这个解决方案没问题,但它会导致大量重复代码,尤其是 XAML。

所讨论的值对象由三到五个属性组成,这些属性通常是 X、Y、Z 和一些辅助 Material 的变体。鉴于此,我曾考虑创建三个 ViewModel 来处理各种可能性,其中每个 ViewModel 都需要公开每个属性的值的属性以及要为每个标签显示的描述(例如“纬度”)。

更进一步,我似乎可以将其简化为一个通用的 ViewModel,它可以处理 N 个属性并使用反射将所有内容连接起来。类似于属性网格的东西,但用于不可变对象(immutable对象)。属性网格的一个问题是我希望能够更改外观,这样我就可以拥有标签和文本框,例如:
Latitude:   [      32 ]  <- TextBox
Longitude: [ 115 ]
Height: [ 12 ]

或将其放在 DataGrid 中,例如:
Latitude  |  Longitude  |  Height
32 115 12

所以我的问题是:

你能想出一个优雅的方法来解决这个问题吗?有没有这样做的图书馆或关于类似事情的文章?

我主要在寻找:
  • 尽量减少代码重复
  • 易于添加新的值对象类型
  • 可以通过某种验证进行扩展
  • 最佳答案

    自定义类型描述符可以用来解决这个问题。在绑定(bind)到位置之前,您的类型描述符可以启动,并提供 get 和 set 方法来临时构建值。提交更改后,它可以构建不可变对象(immutable对象)。

    它可能看起来像这样:

    DataContext = new Mutable(position, 
    dictionary => new Position(dictionary["lattitude"], ...)
    );

    您的绑定(bind)仍可能如下所示:
    <TextBox Text="{Binding Path=Lattitude}" />

    因为 Mutable 对象将“假装”拥有像 Latitude 这样的属性,这要归功于它的 TypeDescriptor。

    或者,您可以在绑定(bind)中使用转换器并提出某种约定。

    您的 Mutable 类将采用当前的不可变对象(immutable对象)和 Func<IDictionary, object>这允许您在编辑完成后创建新的不可变对象(immutable对象)。您的 Mutable 类将使用类型描述符,该描述符将创建 PropertyDescriptors,在设置时创建新的不可变对象(immutable对象)。

    有关如何使用类型描述符的示例,请参见此处:

    http://www.paulstovell.com/editable-object-adapter

    编辑 :如果您想限制创建不可变对象(immutable对象)的频率,您还可以查看您的 Mutable 也可以实现的 BindingGroups 和 IEditableObject。

    关于wpf - 如何在不复制代码的情况下在 WPF 中编辑不可变对象(immutable对象)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/862209/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com