Xamarin.Forms/MAUI中的INotifyPropertyChanged、BindableObject和ObservableObject有何区别?

3

在使用Xamarin.Forms或MAUI创建项目时,我很难理解这三个东西的区别。我知道它们分别是什么——INotifyPropertyChanged是一个接口,当你想要在XAML中使用绑定时需要实现该接口,BindableObject是Xamarin.Forms类,其实现了上述接口,而ObservableObject是Xamarin Community Toolkit中的一个类,也实现了该接口。我只是不太明白它们之间的区别(特别是后面两个),以及何时使用它们?我已经阅读了不同的教程,它们都说不同的事情——你需要自己实现该接口(因此您的视图模型实现该接口),您的视图模型需要继承自BindableObject,或者——如果您正在使用Xamarin Community Toolkit(您可能应该使用/正在使用),则继承自ObservableObject。但是——就像我所说的——为什么您应该使用上述任何一种解决方案而不是其他解决方案呢?

如果您实现了INotifyPropertyChanged接口,Visual Studio(或ReSharper扩展程序,我不确定哪一个)会自动实现它所需的方法并添加以下代码:

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void PropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

但这样会让你的代码变得更冗长/丑陋,所以我理解为什么你想要只从已经实现该接口的类中继承。但是为什么有些人说你应该总是自己实现它呢?当你自己实现它或者从已经实现了它的类中继承时有什么区别吗?此外,如果你决定从一个类中继承 - 为什么要选择其中之一而不是另一个?Xamarin.Forms的文档在这方面非常好,但是它没有提到Xamarin Community Toolkit的存在,Xamarin Community Toolkit的文档没有回答我的问题,也没有说明为什么你应该使用他们的ObservableObject而不是Xamarin.Form内置的BindableObject
2个回答

5

我认为你的困惑源于 BindableObservable 之间的区别。

关于 INotifyPropertyChanged,你大多数是正确的。它是值更改的抽象概念,而不是具体实现。它不仅用于 XAML,还可以用于任何东西。但是我指的是什么呢?

系统的不同部分会因为不同的原因关心值为什么改变。一个类,它根据某些值的更改静默地记录数据到文本文件中,与一个更新应用程序用户界面的类相差很远。

INotifyPropertyChanged 只是一个 机制,用于促进更改通知,没有其他作用。

回到 ObservableObjectBindableObject 之间的区别,它们只是针对不同的用例。

看一下我上面链接的文档。看看 BindableObject 类上有多少个方法?注意 OnPropertyChanged 只是 BindableObject 上的许多方法之一,但在 ObservableObject 上只有两个方法之一

BindableObject 用作 元素 的基类。例如,将按钮的状态更改为在单击后禁用它。或者根据某些更改来更新 Label 的文本值。

ObservableObject 可以用作需要通知其他类有关值更改的任何内容的基类。正如你所指出的那样,它可以避免你一直编写样板 INotifyPropertyChanged 实现。

这个主题还有很多内容,但我不想向你提供大量信息。

如果你正在寻找一些真实世界的例子,请研究 MVVM 设计模式 如何利用一个类向另一个类传递更改的概念。


谢谢!你的回答真的帮了我,消除了困惑。特别感谢你提供有用的链接。但是我还有一个问题,只是为了确认 - 这是否意味着我的ViewModels应该继承自ObservableObject,因为没有必要继承自BindableObject?此外 - 这是否意味着如果我遵循MVVM模式,就不需要从BindableObject继承,因为XAML的代码后台文件已经从ContentPage(间接继承自BindableObject)继承了? - Razwill
1
没问题,谢谢您将其标记为已接受。我正在努力为人们提供出色的Xamarin帮助,以建立声誉 :)你问题的答案是“是的,大多数情况下是这样”。一个好的经验法则是“ViewModels是ObservableObjects,Views是Pages,Views上的元素是BindableObjects”。 - user18270057
1
非常好的回答。关于“视图是页面”的小修正:页面和视图都是VisualElement。所有元素都是BindableObject。 - ToolmakerSteve
@ToolmakerSteve 谢谢!还有一个公正的纠正。当时我尝试避免深入细节,但是在几个月后回顾我的答案,我认为提到这一点是正确的。 - user18270057

3

我认为有关不同类的一些混淆:

  • Xamarin.Forms.BindableObject 旨在用于创建类似具有可绑定属性的自定义视图。它还实现了 INotifyPropertyChanged 接口,但我认为不应将其用于 ViewModel。

  • 来自社区工具包的 ObservableObject 可用作任何您想要使用数据绑定的类的基类,您不需要自己进行实现。

  • 如果对于处理 OnPropertyChanged 有一些自定义要求,那么您确实需要自己实现接口。但如果您只想使用默认行为,ObservableObject 是完全可以的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接