Reputation: 216
Caveat:
Brand new to ReactiveUI. Trying to go full on RxUI with the intention of never setting a view's DataContext. I believe this can be done!
Scenario:
I have a button and the button has a style and that button's style has a MultiDataTrigger with first condition being IsMouseOver and second condition being a property on my ViewModel of type bool. This then changes the background or foreground of the button. Traditionally, you would just bind that second condition to the ViewModel's property.
Is there a feasible way for this interaction to work without using a DataContext yet still have the same outcome I expect? I can't directly access the condition binding since it doesn't have a name. So there has to be some weird setup to get this to work.
Solution not really a fan of:
I could potentially add a control that isn't visible, give it a name, and use the this.OneWayBind() to bind that property to the "IsEnabled" property of this control. In doing so, my second condition of the button's MultiDataTrigger could then use binding based on ElementName and its path of IsEnabled. This would allow me to NOT use a DataContext but seems way too "hacky" for my taste. There's gotta be another way!
Thanks in advance!
Edit 1 - Attempt 1 based off Glenn Watson's comment to the post
this.WhenActivated(disposables =>
{
this.WhenAnyValue(x => x.TheButton.IsMouseOver, x => x.ViewModel.SomeBoolValue).Subscribe(x =>
{
if (!x.Item1)
TheButton.Background = x.Item2 ? Brushes.Gray : Brushes.Blue;
else
TheButton.Background = x.Item2 ? Brushes.Red : Brushes.Green;
}).DisposeWith(disposables);
});
Edit 2 - implemented/using Glenn Watson's answer.
Upvotes: 2
Views: 743
Reputation: 2888
I would recommend something close to the solution you have:
this.WhenAnyValue(x => x.TheButton.IsMouseOver, x => x.ViewModel.SomeBoolValue,
(isMouseOver, boolValue) =>
{
if (isMouseOver)
return boolValue ? Brushes.Gray : Brushes.Blue;
else
return boolValue ? Brushes.Red : Brushes.Green;
})
.BindTo(this, view => view.TheButton.Background)
.DisposeWith(disposables);
The modifications are using the third parameter which takes in a parameterized lambda to the previous two values, then just using BindTo(). It shouldn't be that dissimilar to what you've got.
Upvotes: 3
Reputation: 954
I have a couple of ideas. Dont' have time to try them first but they might help.
You could try embedding the trigger in the button's resources directly and then still using the button name for the onewaybind.
You could try defining a new DataTemplate for the button and target your viewmodel that has the trigger properties.
Upvotes: 0