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
CodePudding user response:
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);