简体   繁体   English

实施行为的更好方法

[英]Better way to implement a behavior

I'm relatively new to WPF and Behaviors. 我是WPF和Behaviors的新手。

I have this behavior, I need to execute DoSomething() every time I set IsRedundant in the ViewModel. 我有这种行为,每次在ViewModel中设置IsRedundant时,都需要执行DoSomething()。

Each time I need to trigger DoSomething, I would need to change the value of the property and this is confusing (if ture => set it to false, If false => set it to true). 每次我需要触发DoSomething时,我都需要更改属性的值,这会造成混淆(如果ture =>设置为false,如果false =>设置为true)。 IsRedundant only used to raise the property changed event and for nothing else. IsRedundant仅用于引发属性更改事件,仅此而已。

Is there a better way of achieving this ? 有没有更好的方法来实现这一目标?

Any ideas ? 有任何想法吗 ?

wpf wpf

  <i:Interaction.Behaviors>
                    <local:UIElementBehavior  Redundant="{Binding IsRedundant, Mode=TwoWay}"/ >
   </i:Interaction.Behaviors>

C# C#

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
        }

    }

Each time I need to trigger DoSomething, I would need to change the value of the property and this is confusing (if true => set it to false, If false => set it to true) 每次我需要触发DoSomething时,都需要更改属性的值,这会造成混淆(如果true =>设置为false,如果false =>设置为true)

The problem is that you are using binding. 问题是您正在使用绑定。 Binding required target to be dependency property. 绑定必需的目标为依赖项属性。 And those are special, their setters aren't called, so you have to use callback to get informed when their value is changed via binding. 而且这些都是特殊的,它们的设置器没有被调用,因此当通过绑定更改其值时,您必须使用回调来获得通知。

Moreover there is internally a check if value is different, for performance reasons callback is not called if value is the same, so you must change it as you do already. 此外,内部会检查值是否不同,出于性能原因,如果值相同,则不会调用回调,因此您必须像已经进行的那样对其进行更改。


An alternative solution is to simply add event in the view model: 另一种解决方案是简单地在视图模型中添加事件:

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);

     ...
}

Now you can subscribe/unsubscribe in the view to/from this event and do something in the event handler. 现在,您可以在视图中订阅/取消订阅该事件/从该事件中取消订阅,并在事件处理程序中执行某些操作。 If you are purist, then refactor code from the view into reusable behavior. 如果您是纯粹主义者,则将视图中的代码重构为可重用的行为。

Is it shorter? 它更短吗? Nope. 不。 Is it more clear? 更清楚了吗? Yes, compared to using bool and such "wonderful" code: 是的,与使用bool和此类“精彩”代码相比:

IsRedundant = false;
IsRedundant = true; // lol

I was using bool properties like you do to inform the view in the past. 我曾经像过去一样使用bool属性来告知视图。

Then I used events. 然后我使用事件。

Now I use combination of both. 现在,我将两者结合使用。 Every view model already implements INotifyPropertyChanged so why not use it? 每个视图模型已经实现INotifyPropertyChanged ,为什么不使用它呢?

Think about IsRedundant as a state . IsRedundant视为一种状态 It can be used not only to trigger some method, but also used by the view to run animations via data triggers, control visibility of dynamic layout, etc. So you need a normal bool property in view model. 它不仅可以用来触发某些方法,还可以被视图用来通过数据触发器,控制动态布局的可见性等来运行动画。因此,在视图模型中需要一个普通的bool属性。

The view then can subscribe to/unsubscribe from PropertyChanged and simply have to check: 然后,该视图可以从PropertyChanged订阅/取消订阅,只需检查以下内容:

if(e.PropertyName == nameof(ViewModel.IsRedudant)) { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM