时间:2011-01-06 16:41:20

标签: c# wpf wpf-controls binding

1 个答案:

答案 0 :(得分:1)

保留EventHandler的本地副本的原因是WPF命令子系统在内部使用弱引用,因此我们需要保留对添加到{{1的特定委托对象的引用事件。事实上,只要我们添加到任何指挥子系统事件,我们也应该像CanExecuteChanged那样观察这种做法。

您的问题的简短回答是SecurityTypeChanged 可以是静态的,但您必须小心初始化一次。它可以是静态的原因是如果canExecuteChangedHandler是静态的,所有new EventHandler(CanExecuteChanged)都会做同样的事情。初始化一次的原因是不同的实例是不同的。

具有正确只读语义的私有属性是:

CanExecuteChanged

但这仅在static EventHandler canExecuteChangedHandler { get { if (internalCanExecuteChangedHandler == null) internalCanExecuteChangedHandler = new EventHandler(CanExecuteChanged); return internalCanExecuteChangedHandler; } } static EventHandler internalCanExecuteChangedHandler; 为静态时有效。如果不是,则删除CanExecuteChanged限定符。在任何一种情况下,您都必须小心实际使用属性。

在这个特定示例中,第二次调用static时,第一个AddSecureCommand有被垃圾回收的风险。

最后,如果这听起来像黑魔法,这里有一个代码示例来展示正在发生的事情。

canExecuteChangedHandler

这会产生此输出:

public class Container
{
    private WeakReference reference;
    public object Object
    {
        get { return reference.IsAlive ? reference.Target : null; }
        set { reference = new WeakReference(value); }
    }
}

public class DelegateTest
{
    private EventHandler eventHandler;
    private Container container1;
    private Container container2;

    void MyEventHandler(object sender, EventArgs args)
    {
    }

    public DelegateTest()
    {
        this.eventHandler = new EventHandler(MyEventHandler);
        this.container1 = new Container { Object = this.eventHandler };
        this.container2 = new Container { Object = new EventHandler(MyEventHandler) };
        GC.Collect();
        Console.WriteLine("container1: {0}", this.container1.Object == null);
        Console.WriteLine("container2: {0}", this.container2.Object == null);
    }
}

表示在垃圾收集期间第二个容器的container1: False container2: True 垃圾收集“从其下面”。这是设计弱引用的工作方式,对你的解释需要自己保持对它的引用。