In my WPF+ReactiveUI+DynamicData project I can't make binding of ListBox.ItemsSource to ReadOnlyObservableCollection working. I successfully populate data from by backend service to my ViewModel
public class RecordingsListViewModel: ReactiveObject
{
private readonly ReadOnlyObservableCollection<RecordingViewModel> _recordings;
public ReadOnlyObservableCollection<RecordingViewModel> Recordings => _recordings;
public RecordingsListViewModel(IRecordingsService recordindsService)
{
recordindsService.RecordingsList.Connect()
.Transform(rec => new RecordingViewModel(rec as IRecordingModel))
.Bind(out _recordings)
.Subscribe();
}
}
My View:
<reactiveui:ReactiveUserControl x:Class="MyProject.Views.RecordingsListView"
x:TypeArguments="vm:RecordingsListViewModel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:MyProject.ViewModels"
xmlns:reactiveui="http://reactiveui.net"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ListBox x:Name ="RecordingsListBox" HorizontalContentAlignment="Stretch"/>
</reactiveui:ReactiveUserControl>
In my code behind I'm trying to bind but it doesn't work
{
public static readonly DependencyProperty ViewModelProperty = DependencyProperty
.Register(nameof(ViewModel), typeof(RecordingsListViewModel), typeof(RecordingsListView));
public RecordingsListViewModel ViewModel
{
get => (RecordingsListViewModel)GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
}
object IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (RecordingsListViewModel)value;
}
public RecordingsListView()
{
ViewModel = Locator.Current.GetService<RecordingsListViewModel>();
InitializeComponent();
this.WhenActivated(d =>
{
this.OneWayBind(ViewModel,
vm => ViewModel.Recordings,
view => view.RecordingsListBox.ItemsSource).DisposeWith(d);
});
}
}
There is an error in output, but it is not crashing app
PropertyBinderImplementation: view.RecordingsListBox.ItemsSource Binding received an Exception! - System.NotSupportedException: Unsupported expression of type 'Constant'. Did you miss the member access prefix in the expression?
at ReactiveUI.ExpressionMixins.GetExpressionChain(Expression expression) in /_/src/ReactiveUI/Mixins/ExpressionMixins.cs:line 78
at ReactiveUI.ReactiveNotifyPropertyChangedMixin.SubscribeToExpressionChain[TSender,TValue](TSender source, Expression expression, Boolean beforeChange, Boolean skipInitial, Boolean suppressWarnings) in /_/src/ReactiveUI/Mixins/ReactiveNotifyPropertyChangedMixin.cs:line 140
at ReactiveUI.WhenAnyMixin.WhenAnyDynamic[TSender,TRet](TSender sender, Expression property1, Func`2 selector) in /_/src/ReactiveUI/VariadicTemplates.cs:line 99
at ReactiveUI.Reflection.<>c__DisplayClass15_0`2.<ViewModelWhenAnyValue>b__2(Object x) in /_/src/ReactiveUI/Expression/Reflection.cs:line 407
at System.Reactive.Linq.ObservableImpl.Select`2.Selector._.OnNext(TSource value) in /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Select.cs:line 39
I'm googling for this error and relevant examples for almost 16 hours, tried lots of code adjustments without any luck. Any ideas much appreciated
Many thanks to Glenn Watson and
Đøharrrck comments. I finally fixed it.
The problem was in wrong access to viewModel in binding.
Was:
this.OneWayBind(ViewModel,
vm => ViewModel.Recordings,
view => view.RecordingsListBox.ItemsSource).DisposeWith(d);
Should be:
this.OneWayBind(ViewModel,
vm => vm.Recordings,
view => view.RecordingsListBox.ItemsSource).DisposeWith(d);