Using ReactiveUI BindTo () to update the XAML property generates a warning

I am trying to update an element property in a XAML view:

this.WhenAnyValue(x => x.ViewModel.IsEnabled).BindTo(this, x => x.MyButton.IsEnabled);

This works as expected, however, it generates a warning at runtime:

POCOObservableForProperty: rx_bindto_test.MainWindow is a POCO type and will not send notification of changes when WhenAny returns only one value!

I can get rid of the warning by changing the expression to:

this.WhenAnyValue(x => x.ViewModel.IsEnabled).Subscribe(b => MyButton.IsEnabled = b);

but I'm still wondering why this does not work with BindTo ().

Edit: there is even a regular Bindand OneWayBindgenerate this warning.

  • What am I doing wrong here?
  • ViewModel , ? ( , ReactiveUI POCO), ReactiveObject, # .

MainWindow.xaml.cs

public partial class MainWindow : Window, IViewFor<MyViewModel>, IEnableLogger {
    public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register("ViewModel",
        typeof(MyViewModel), typeof(MainWindow));

    public MyViewModel ViewModel {
        get { return (MyViewModel)GetValue(ViewModelProperty); }
        set { SetValue(ViewModelProperty, value); }
    }

    object IViewFor.ViewModel {
        get { return ViewModel; }
        set { ViewModel = (MyViewModel)value; }
    }

    public MainWindow() {
        InitializeComponent();

        this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContext);

        this.WhenAnyValue(x => x.ViewModel.IsEnabled).BindTo(this, x => x.MyButton.IsEnabled);

        ViewModel = new MyViewModel();
        ViewModel.IsEnabled = true;
    }
}

MainWindow.xaml

<Window x:Class="rx_bindto_test.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">
    <Grid>
        <Button x:Name="MyButton">My Button</Button>
    </Grid>
</Window>

MyViewModel.cs

public class MyViewModel : ReactiveObject, IEnableLogger {
    private bool isEnabled;

    public bool IsEnabled {
        get { return isEnabled; }
        set { this.RaiseAndSetIfChanged(ref isEnabled, value); }
    }
}
+4
2

, , "MyButton", ViewModel.

MyButton - "" - ( INPC, DependencyObject), .

, POCO ( ) FrameworkElement, XAML ( ):

Locator.CurrentMutable.Register(() => new CustomPropertyResolver(), typeof(ICreatesObservableForProperty));

public class CustomPropertyResolver : ICreatesObservableForProperty
{
    public int GetAffinityForObject(Type type, string propertyName, bool beforeChanged = false)
    {
        if (!typeof(FrameworkElement).IsAssignableFrom(type))
            return 0;
        var fi = type.GetTypeInfo().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)
          .FirstOrDefault(x => x.Name == propertyName);

        return fi != null ? 2 /* POCO affinity+1 */ : 0;
    }

    public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, bool beforeChanged = false)
    {
        var foo = (FrameworkElement)sender;
        return Observable.Return(new ObservedChange<object, object>(sender, expression), new DispatcherScheduler(foo.Dispatcher))
            .Concat(Observable.Never<IObservedChange<object, object>>());
    }
}
+2

, , , - . , :

this.OneWayBind(ViewModel x => x.IsEnabled, x => y.MyButton.IsEnabled);

, , IsEnabled ( RxUI, !).

() :

  • . .
  • . . VM , MVVM. ( ). (), - ListView Quake .
0

Source: https://habr.com/ru/post/1589024/


All Articles