我对WPF和行为相对较新。
我有这种行为,每次在ViewModel中设置IsRedundant时,我都需要执行DoSomething()。
每次我需要触发DoSomething时,我需要更改属性的值,这是令人困惑的(如果ture =>设置为false,如果false =>设置为true)。 IsRedundant仅用于提升属性更改事件,而不是其他任何内容。
有没有更好的方法来实现这一目标?
有什么想法吗?
<i:Interaction.Behaviors>
<local:UIElementBehavior Redundant="{Binding IsRedundant, Mode=TwoWay}"/ >
</i:Interaction.Behaviors>
class UIElementBehavior : Behavior<UIElement>
{
public static readonly DependencyProperty RedundantProperty = DependencyProperty.Register(
"Redundant",
typeof(bool),
typeof(UIElementBehavior),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, DoSomething));
public bool Redundant
{
get { return (bool)GetValue(RedundantProperty); }
set { SetValue(RedundantProperty, value); }
}
private static void DoSomething(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//Do something on the AssociatedObject
}
}
答案 0 :(得分:0)
每次我需要触发DoSomething时,我需要更改属性的值,这是令人困惑的(如果true =&gt;设置为false,如果false =&gt;将其设置为true)
问题是你正在使用绑定。绑定所需的目标是依赖属性。这些是特殊的,它们的setter不会被调用,所以当你的值通过绑定改变时,你必须使用回调来获取信息。
此外,内部检查值是否不同,出于性能原因,如果值相同则不会调用回调,因此必须更改它。
另一种解决方案是在视图模型中简单地添加事件:
public class ViewModel: INotifyPropertyChanged
{
public EventHandler SomethingHappens;
// call this to tell something to listener if any (can be view or another view model)
public OnSomethingHappens() => SomethingHappens?.Invoke(this, EventArgs.Empty);
...
}
现在,您可以在视图中订阅/取消订阅此事件,并在事件处理程序中执行某些操作。如果您是纯粹主义者,则将视图中的代码重构为可重用行为。
更短吗?不。它更清楚了吗?是的,与使用bool
和“精彩”代码相比:
IsRedundant = false;
IsRedundant = true; // lol
我过去使用bool
属性来通知视图。
然后我使用了活动。
现在我使用两者的组合。每个视图模型都已实现INotifyPropertyChanged
,为什么不使用它?
将IsRedundant
视为州。它不仅可用于触发某些方法,还可用于视图通过数据触发器运行动画,控制动态布局的可见性等。因此,您需要在视图模型中使用普通bool
属性。
然后视图可以订阅/取消订阅PropertyChanged
,只需检查:
if(e.PropertyName == nameof(ViewModel.IsRedudant)) { ... }