RxUI - WPF - 没有 DataContext 的 Style DataTrigger 绑定
RxUI - WPF - Style DataTrigger binding with no DataContext
警告:
ReactiveUI 的全新功能。试图完全使用 RxUI 以从不设置视图的 DataContext。我相信这是可以做到的!
场景:
我有一个按钮,该按钮有一个样式,该按钮的样式有一个 MultiDataTrigger,第一个条件是 IsMouseOver,第二个条件是 属性 在我的 bool 类型的 ViewModel 上。然后这会更改按钮的背景或前景。传统上,您只需将第二个条件绑定到 ViewModel 的 属性.
是否有一种可行的方法可以使这种交互在不使用 DataContext 的情况下工作,但仍然具有我期望的相同结果?我无法直接访问条件绑定,因为它没有名称。所以必须有一些奇怪的设置才能让它工作。
解决方案不太喜欢:
我可能会添加一个不可见的控件,为其命名,然后使用 this.OneWayBind() 将 属性 绑定到此控件的 "IsEnabled" 属性 .这样做时,按钮的 MultiDataTrigger 的第二个条件可以使用基于 ElementName 及其 IsEnabled 路径的绑定。这将允许我不使用 DataContext 但似乎 "hacky" 符合我的口味。一定有别的办法!
提前致谢!
编辑 1 - 尝试 1 基于 Glenn Watson 对 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);
});
编辑 2 - implemented/using Glenn Watson 的回答。
我有几个想法。没有时间先尝试它们,但它们可能会有所帮助。
您可以尝试将触发器直接嵌入到按钮的资源中,然后仍然使用单向绑定的按钮名称。
您可以尝试为按钮定义一个新的 DataTemplate 并定位具有触发器属性的视图模型。
我会推荐一些与您的解决方案接近的东西:
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);
修改是使用第三个参数,它接受前两个值的参数化 lambda,然后只使用 BindTo()。它应该与您所拥有的没有什么不同。
警告:
ReactiveUI 的全新功能。试图完全使用 RxUI 以从不设置视图的 DataContext。我相信这是可以做到的!
场景:
我有一个按钮,该按钮有一个样式,该按钮的样式有一个 MultiDataTrigger,第一个条件是 IsMouseOver,第二个条件是 属性 在我的 bool 类型的 ViewModel 上。然后这会更改按钮的背景或前景。传统上,您只需将第二个条件绑定到 ViewModel 的 属性.
是否有一种可行的方法可以使这种交互在不使用 DataContext 的情况下工作,但仍然具有我期望的相同结果?我无法直接访问条件绑定,因为它没有名称。所以必须有一些奇怪的设置才能让它工作。
解决方案不太喜欢:
我可能会添加一个不可见的控件,为其命名,然后使用 this.OneWayBind() 将 属性 绑定到此控件的 "IsEnabled" 属性 .这样做时,按钮的 MultiDataTrigger 的第二个条件可以使用基于 ElementName 及其 IsEnabled 路径的绑定。这将允许我不使用 DataContext 但似乎 "hacky" 符合我的口味。一定有别的办法!
提前致谢!
编辑 1 - 尝试 1 基于 Glenn Watson 对 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);
});
编辑 2 - implemented/using Glenn Watson 的回答。
我有几个想法。没有时间先尝试它们,但它们可能会有所帮助。
您可以尝试将触发器直接嵌入到按钮的资源中,然后仍然使用单向绑定的按钮名称。
您可以尝试为按钮定义一个新的 DataTemplate 并定位具有触发器属性的视图模型。
我会推荐一些与您的解决方案接近的东西:
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);
修改是使用第三个参数,它接受前两个值的参数化 lambda,然后只使用 BindTo()。它应该与您所拥有的没有什么不同。