0

I'm trying to make good use of ReactiveList and I think I'm close.

My expectation is that only "toyota" is shown after the user presses the filter button

XAML (yes, quick n dirty, no command for the Filter)

<Window
    x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow"
    Height="350"
    Width="525">
    <StackPanel>
        <ComboBox
            ItemsSource="{Binding Path=CarsVM}"
            DisplayMemberPath="Name" />

        <Button
            Click="ButtonBase_OnClick">
            Filter
        </Button>

    </StackPanel>
</Window>

The code

using System.Windows;
using ReactiveUI;

namespace WpfApplication1
{

    public partial class MainWindow
    {
        private readonly ViewModel _viewModel;

        public MainWindow()
        {
            InitializeComponent();

            _viewModel = new ViewModel();
            DataContext = _viewModel;
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            _viewModel.ChangeFilter();
        }
    }
}

public class CarViewModel : ReactiveObject
{
    private bool _isVisible = true;

    public CarViewModel(string name)
    {
        Name = name;
    }

    public bool IsVisible
    {
        get { return _isVisible; }
        set
        {
            _isVisible = value;
            this.RaiseAndSetIfChanged(ref _isVisible, value);
        }
    }

    public string Name { get; set; }
}

public class ViewModel
{
    private readonly ReactiveList<CarViewModel> _cars = new ReactiveList<CarViewModel>
    {
        new CarViewModel("bmw"),
        new CarViewModel("toyota"),
        new CarViewModel("opel")
    };


    public ViewModel()
    {
        _cars.ChangeTrackingEnabled = true;

        CarsVM = _cars.CreateDerivedCollection(x => x, x => x.IsVisible);
    }

    public IReactiveDerivedList<CarViewModel> CarsVM { get; set; }

    public void ChangeFilter()
    {
        foreach (var car in _cars)
        {
            car.IsVisible = car.Name.Contains("y");
        }
    }
}
buckley
  • 13,690
  • 3
  • 53
  • 61

1 Answers1

1

Your bug is in the setter of IsVisible. By pre-assigning the value of _isVisible, RaiseAndSetIfChanged always thinks that the value has never changed. Remove _isVisible = value; and everything should work.

Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • Ha! Of course. When discovering a framework common sense seems to be disabled. Thx Paul. A temporal coupling is always tricky in the beginning – buckley Sep 13 '14 at 07:16
  • There is not temporal coupling... The RaiseAndSet does 2 things :) – buckley Sep 15 '14 at 07:55