ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#-ReactiveList问题

2019-11-21 17:05:36  阅读:225  来源: 互联网

标签:reactive-programming reactiveui c


我们对ReactiveUI相对较新,因此这可以解释为什么我们在使视图模型正常工作时遇到一些问题.

在我们的视图模型中,我们有一个类的ReactiveList,在该类中有一个“ selected”的.

在视图模型中,我们希望有一个“ AnySelected”属性,这样,如果列表中至少有1个项目标记为选中,则AnySelected为true.

我们很难完成这项工作.

作为一个只有字符串的小型测试应用程序,我们已经尝试过了,但是没有出现有关更改发生的消息.

public class TestRx : ReactiveObject
{
    private ReactiveList<string> mySelectedItems;

    public ReactiveList<string> MySelectedItems
    {
        get { return mySelectedItems; }
        set { this.RaiseAndSetIfChanged(ref mySelectedItems, value); }
    }

    public TestRx()
    {
        var firstList = new ReactiveList<string>();

        var t = this.WhenAnyValue(x => x.MySelectedItems);
        var t1 = t.Select(x => x ?? new ReactiveList<string>());

        var changed = t1.Select(x => x.Changed.Select(_ => Unit.Default));
        var itemChanged = t1.Select(x => x.ItemChanged.Select(_ => Unit.Default));
        var countChanged = t1.Select(x => x.CountChanged.Select(_ => Unit.Default));

        t.Subscribe(x => Debug.WriteLine("T HAS CHANGED {0}", x == firstList));
        t1.Subscribe(z => Debug.WriteLine("T1 Changed {0}", z == firstList));

        changed.Subscribe(x => Debug.WriteLine("Changed :"));
        itemChanged.Subscribe(x => Debug.WriteLine("Item Changed :"));

        var replacementList = new ReactiveList<SelItem>(new[] {
                new SelItem() { Selected = false } 
        });

        Debug.WriteLine("***********************Assign 1st list");
        MySelectedItems = firstList;
        Thread.Sleep(100);

        Debug.WriteLine("***********************Adding item 2 list");
        MySelectedItems.Add("a new string");
        // we don't get any debug messages  as a result of the above
        Thread.Sleep(100);

        Debug.WriteLine("***********************Assign null");
        MySelectedItems = null;
        Thread.Sleep(100);
    }
}

我们做错了什么?

解决方法:

这是一种常见的模式,但是实现起来有些棘手,因为您必须处理以下所有情况:

>清单已设定
>列表项更改
>任何项目上的“选定”属性都会更改.请记住,您要观看的物品因#1或#2而改变.

我该怎么做?

这是一种方法.这很复杂,这暗示着将来的RxUI版本可以使事情变得更好的地方,但是这是您现在可以做的.

IObservable<bool> WhenAnyAreTrue(IEnumerable<ViewModel> currentElements)
{
    // NB: 'Unit' here means, we don't care about the actual value, just
    // that something changed
    var notifyWhenAnySelectedItemChanges = currentElements
        .Select(x => x.WhenAny(y => y.Selected, _ => Unit.Default).Skip(1))
        .Merge();

    return notifyWhenAnySelectedItemChanges
        .StartWith(Unit.Default)
        .Select(_ => currentElements.Any(x => x.Selected));
}

// Any time MySelectedItems change or when the items in it change,
// create a new WhenAnyAreTrue and switch to it
this.WhenAnyObservable(x => x.MySelectedItems.ItemsChanged)
    .Select(_ => WhenAnyAreTrue(MySelectedItems))
    .Switch()
    .ToProperty(this, x => x.AnySelected, out anySelected);

标签:reactive-programming,reactiveui,c
来源: https://codeday.me/bug/20191121/2053432.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有