在ObservableCollection中更改集合时,向ReactiveList添加新条目

时间:2017-11-09 13:55:51

标签: c# reactiveui

我有ObservableCollection来自TcpClient。当新数据到达时(添加新项目),我想在ItemsControl内创建新的按钮。它以旧的方式工作(使用CollectionChanged),但我不能使用 ReactiveUI

我是ReactiveUI的新手,对我来说很难入手。你可以帮助我,让我走上正确的道路,或者提供一些示例代码吗?

理念:

public class ChooseMachineViewModel : ReactiveObject
{
    public ReactiveList<Button> ButtonList { get; set; }
    private Dictionary<ushort, Button> addressToButton;

    //This one is normaly in another class and will be filled by a TcpClient
    public readonly ObservableCollection<WWSS.Message.CUStatus> ControlUnitsStatus;

    public ChooseMachineViewModel()
    {



        //TODO: Make this Reactive!
        //The ButtonList for an ItemsControl
        ButtonList = new ReactiveList<Button>();
        //The Dictonary for addresses -> Button
        addressToButton = new Dictionary<ushort, Button>();
        //The ObservableCollection filled by a TCP Server
        ControlUnitsStatus.CollectionChanged += ControlUnitsStatus_CollectionChanged;

    }


    private void ControlUnitsStatus_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {

        if (e.NewItems != null)
        {
            foreach (WWSS.Message.CUStatus stat in e.NewItems)
            {
                TryAddButton(stat);//When new Status arrive, try to create new button
            }
        }
        if (e.OldItems != null)
        {
            foreach (WWSS.Message.CUStatus stat in e.OldItems)
            {
                TryRemoveButton(stat);//When Status removed, try to remove the button
            }
        }
    }

    private bool TryAddButton(WWSS.Message.CUStatus status)
    {
        if (!addressToButton.ContainsKey(status.Address))//if the Address is already in the dictonary don't create a button
        {
            var but = new Button { Content = status.Address.ToString() };
            addressToButton.Add(status.Address, but);
            ButtonList.Add(but);
            return true;
        }
        return false;
    }
    private void TryRemoveButton(WWSS.Message.CUStatus status)
    {
        if (addressToButton.ContainsKey(status.Address))
        {
            ButtonList.Remove(addressToButton[status.Address]);
            addressToButton.Remove(status.Address);

        }
    }
}

1 个答案:

答案 0 :(得分:0)

诀窍是使用CreateDerivedCollection

public class ChooseMachineViewModel : ReactiveObject
{
    public IReactiveDerivedList<Button> ButtonList { get; set; }

    public ChooseMachineViewModel(ObservableCollection<CUStatus> source)
    {
        addressToButton = new Dictionary<ushort, Button>();
        ButtonList = ControlUnitsStatus.CreateDerivedCollection(status => new Button { Content = status.Address.ToString() },
                                                    status => !ButtonList.Any(button => button.Content.ToString().Equals(status.Address.ToString())));
    }
}