- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 WPF MVVM 应用程序。我的模型对象是我可以完全控制的 POCO。这些对象中的某些属性之间存在关系。
例如:假设我有
public class Model
{
public ObservableCollection<double> XCoordinates { get; set; } // Cumulative sum of DistancesBetweenXCoordinates.
public ObservableCollection<double> DistancesBetweenXCoordinates { get; set; } // {x[1]-x[0], x[2]-x[1], ..., x[n]-x[n-1]}
public double TotalLength { get; set; } // Sum of DistancesBetweenXCoordinates.
}
我希望最终用户能够编辑距离列表或 x 坐标列表,并且其他属性应该自动更新。到目前为止,我已经使用 INPC 事件完成了这项工作,但这很快就会变得太困惑。一些 UI 更新是在每次 PropertyChange 之后完成的,所以我想对此进行优化。
由于我的真实应用中的一些属性更新对性能的影响可以忽略不计,所以我不想使用“计算属性”,例如
public double TotalLength => DistancesBetweenXCoordinates.Sum();
据我了解,ReactiveUI 框架似乎具有我正在寻找的功能。不过我有一些问题:
1) 我目前正在使用另一个我不想完全放弃的框架 (Catel)。我可以使用 ReactiveUI 中的 .WhenAny()
等而不继承 ReactiveObject
(例如,仅通过实现 IReactiveObject
)吗?
2) 我见过的几乎所有示例都继承自 ViewModel 中的 ReactiveObject
。这是实现我想要的目标的首选方式吗?在我的模型中实现它不是更有意义吗?如果我的模型应该只是一个“愚蠢的”POCO,没有任何机制来保持所有相关属性都是最新的,那么这是我的 Reactive VM 的责任吗?
如果能提供一个简单的示例或其他指导,我将不胜感激。
最佳答案
INotifyPropertyChanged
,您可以使用.WhenAny()
ReactiveObject
可用于 ViewModel 和 Model 类。它实际上只是一个“ react 性”对象。即像 System.Object
。 (不相信我?查看 the source 。)ObservableAsPropertyHelper
计算依赖于其他 react 属性或事件的属性。 (参见 docs)有几种方法可以处理这个问题,但特别是您似乎想要推理出一些事情:
ReactiveObject
应该仅限于 ViewModels 吗?它在普通模型类中有用吗?首先,您已经注意到,ReactiveUI 的很多吸引力都来自 .WhenAny()
中包含的强大功能。你能在框架之间使用这些方法吗,是! .WhenAny()
、.WhenAnyValue()
、.WhenAnyObservable()
方法适用于任何实现INotifyPropertyChanged
。 ( Related Docs )
事实上,您现有的框架很可能已经在它们自己的许多类型上实现了 INotifyPropertyChanged
,因此 .WhenAny()
自然会扩展以无缝地处理这些对象。你几乎从不真正需要 ReactiveObject
。它只会让您的生活更轻松。
Note: This is actually one of the core values of ReactiveUI. That at the core, ReactiveUI is really just a bunch of extension methods designed to make working with observables easier in the existing .Net world. This makes interoperability with existing code one of ReactiveUI's most compelling features.
现在,ReactiveObject
应该用于普通的“哑”模型吗?我想这取决于你希望责任归于何处。如果您希望您的模型类只包含规范化状态而根本不包含任何逻辑,那么可能不会。但是,如果您的模型旨在处理状态和领域相关的逻辑,那为什么不呢?
Note: There's a larger philosophical debate here about the single responsibility principal, software architecture, and MVVM, but that's probably for Programmers SE.
在这种情况下,我们关心通知监听器有关某些计算属性(例如 TotalLength
)的更新。 (即我们的模型包含一些逻辑)ReactiveObject
帮助我们做到这一点吗?我想是的。
在您的场景中,我们希望在添加或更改元素时根据DistancesBetweenXCoordinates
计算TotalLength
。我们可以结合使用 ReactiveObject
和 ObservableAsPropertyHelper
。 ( Related Docs )
例如:
class Model : ReactiveObject
{
// Other Properties Here...
// ObservableAsPropertyHelper makes it easy to map
// an observable sequence to a normal property.
public double TotalLength => totalLength.Value;
readonly ObservableAsPropertyHelper<double> totalLength;
public Model()
{
// Create an observable that resolves whenever a distance changes or
// gets added.
// You would probably need CreateObservable()
// to use Observable.FromEventPattern to convert the
// CollectionChanged event to an observable.
var distanceChanged = CreateObservable();
// Every time that a distance is changed:
totalLength = distanceChanged
// 1. Recalculate the new length.
.Select(distances => CalculateTotalLength(distances))
// 2. Save it to the totalLength property helper.
// 3. Send a PropertyChanged event for the TotalLength property.
.ToProperty(this, x => x.TotalLength);
}
}
在上面,每次 distanceChanged
observable 解析时,都会重新计算 TotalLength
。例如,每当 DistanceBetweenXCoordinates
发出 CollectionChanged
事件时。此外,因为这只是一个普通的可观察对象,您可以在后台线程上进行计算,从而使您可以在长时间操作期间保持 UI 响应。计算完成后,将为 TotalLength
发送 PropertyChanged
事件。
关于c# - ReactiveUI - 具有许多相关属性的模型对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45990829/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!