Xamarin + Prism:气泡 属性 从分层模型/视图模型或...更改事件?

Xamarin + Prism: bubble property change events from hierarchical model / view model or ...?

我一直在尝试找到解决这个问题的正确方法,将 Prism 与 Xamarin Forms 结合使用:

我有一个模型 class,客户,它包含另一个 class,地址为 属性。在我看来,我显示了来自 objects 的字段。我想要一个 "save" 按钮,只有在您对这些模型进行一些更改后才会启用该按钮。

现在,按钮绑定到命令,具有相应的 CanSave() 函数,就像 DelegateCommands 一样。我正在尝试找到一种方法,我可以在我的视图模型上以单个 IsDirty 属性 结束,在对基础模型进行任何更改后达到 "true" 。

MVVM 方法

我首先想到的是 "purist" mvvm 方法。 "flat" 视图模型,具有每个视觉元素的属性,实现为 Prism BindableObject,其中每个 getter/setter gets/sets 值 from/to 基础模型 classes。

虽然失败了,因为 SetProperty<> 有一个 ref 参数,我不能在其中使用模型中的属性。

over-engineered 方法[?]

我想到的第二件事是,如果我的内部模型本身就是可观察对象,我就可以在整个树中监听所有这些模型的变化。这开辟了一个全新的问题世界。我是否在我的视图模型中注册 属性 更改侦听器?我是否使内部模型可观察,并让 parents 监听其 children 上的更改事件并传播它?

可观察模型方法不会很快变成事件处理程序地狱吗?

最简单的事情

最后,最简单的事情。我有一个扁平的可观察 ViewModel,只有 reads/writes 值 to/from 读取和保存时的实际内部层次模型

大家怎么看?

也许我没有理解你的问题,但我想知道你为什么将自己限制在像 SetProperty 这样的小辅助函数上。它有 4 Lines of code。它所做的只是检查是否相等、设置值和引发事件。

您可以像这样轻松创建另一个辅助函数。

MyBindableBase

protected virtual bool SetProperty<T>(Func<T> get, Action<T> set, T value, [CallerMemberName] string propertyName = null)
{
    if (object.Equals(get(), value)) return false;

    set(value);
    OnPropertyChanged(propertyName);

    return true;
}

型号

class Model
{
    public string Property { get; set; }
}

ViewModel

class ViewModel : BindableBase
{
    private Model Model { get; set; }

    public string Property
    {
        get { return Model.Property; }
        set { SetProperty(() => Model.Property, x => Model.Property = x, value); }
    }
}

我认为你可以缩短使用时间,如果你为映射引入一些命名规则and/or使用反射。

好吧,最后我选择了选项 3,这是我能做的最简单的事情。

我倾向于从我的模型中返回属性,这很容易,并且使用可为空的 [?.] 语法它也是空安全的,但我发现有时我必须包装实际模型属性具有比我的实际数据库模型 类 更 UI 友好的东西,公开 more/different 属性。

所以,我就这样做了,直到一些其他的复杂性迫使我再次改变主意:)

非常感谢@Sven-Michael Stübe 和@adminSoftDK 的帮助