RxUI ObservableAsPropertyHelper 不适用于 XAML 绑定

Posted

技术标签:

【中文标题】RxUI ObservableAsPropertyHelper 不适用于 XAML 绑定【英文标题】:RxUI ObservableAsPropertyHelper not working for XAML bindings 【发布时间】:2015-03-28 01:51:46 【问题描述】:

我有以下视图模型类(基于RxUI design guidelines):

public class SomeViewModel : ReactiveObject

    private readonly ObservableAsPropertyHelper<int> m_count;

    public ReactiveCommand<object> AddItem  get; set; 

    public int Count
    
        get  return m_count.Value; 
    

    public IReactiveList<string> SomeList  get; private set; 

    public SomeViewModel ()
    
        SomeList = new ReactiveList<string>();

        AddItem = ReactiveCommand.Create();
        AddItem.Subscribe(x => SomeList.Add("new item"));

        m_count = SomeList.CountChanged.ToProperty(this, x => x.Count, 100);

        SomeList.Add("first item");
    

还有以下 XAML 绑定:

<Button Command="Binding AddItem" Content="Binding Count" />

显示我的视图时,按钮内容是 100 而不是 1。然后当点击按钮时,内容更新为 2,然后是 3,然后是 4,等等。

为什么没有观察到对SomeList.Add() 的第一次调用?

【问题讨论】:

【参考方案1】:

这是一个微妙的错误。 ToProperty 是惰性,这意味着它在设置 XAML 绑定之前不会开始订阅(即调用 SomeList 之后)。您应该可以通过以下方式解决此问题:

 SomeList.CountChanged.StartWith(SomeList.Count).ToProperty(this, x => x.Count, 100);

【讨论】:

这个修复对我的实际用例没有好处。上面的示例被简化以演示该问题。实际上,我对SomeList.Add("first item") 的调用不会发生在构造函数中,而是发生在 AutoMapper 映射中。换句话说,SomeViewModel 由 AutoMapper 创建,然后 AutoMapper 检测到 SomeList 已在构造函数中初始化,因此它只需调用 SomeList.AddRange() 以使用映射值填充列表。似乎没有观察到的是这个AddRange() 调用。 我真正需要完成的是让我的 UI 知道列表已更新,以便它可以显示正确的初始值,而不仅仅是默认值。我只使用CountChanged observable,因为它便于检测列表中的变化(我想知道添加和删除的项目,而不必观看两个不同的 observables),但我并不真正关心实际计数. 仅供参考,您上面的答案实际上也没有修复上面的示例代码。按钮内容在 UI 中显示的初始值仍然是 100。 如果我给Count 一个setter 来引发它自己的属性更改事件,并简单地将Subscribe() 设置为SomeList.ItemChanged 来设置Count 我自己,那么一切都会按预期工作。但我希望了解为什么使用 ObservableAsPropertyHelper 的推荐方法不起作用。 同样的问题,无法通过 StartWith().ToProperty() 获得通知。除了 Subscribe() 还有其他方法吗?

以上是关于RxUI ObservableAsPropertyHelper 不适用于 XAML 绑定的主要内容,如果未能解决你的问题,请参考以下文章