WPF CustomControl:在PropertyChangedCallback之后调用的OnApplyTemplate

时间:2009-08-19 10:02:36

标签: wpf propertychanged custom-controls

我正在创建一个WPF CustomControl,它具有PropertyChangedCallback的依赖属性。在那个Callback方法中,我尝试使用GetTemplateChild()方法设置我从OnApplyMethod检索的一些控件部分的值。

问题是在OnApplyTemplate之前调用了PropertyChangedCallback(在某些系统上),因此控件部分仍为空。

我目前使用的解决方法是将PropertyChangedCallback中的e.NewValue保存到成员变量,然后在OnApplyTemplate()中调用SetValue(dp,_savedValue)。

处理此问题的正确方法是什么,或者我已经使用了最佳解决方案?

1 个答案:

答案 0 :(得分:7)

这就是我们所做的 - 并没有解决原则中的问题,而是提供了明确的解决方法。

  1. 为DP值更改事件创建一个处理程序,让它为OnValueChanged()。通常不需要参数,因为您知道哪个DP已更改并且始终可以获取其当前值。

  2. 使用构造函数创建一个名为DeferredAction的类/结构,接受System.Action(这将是对OnValueChanged()的引用)。该类将具有属性Action和一个名为Execute()的方法。

  3. 以下是我使用的内容:

    class DeferredAction
    {
       private Action action;
    
        public DeferredAction(Action action)
        {
            this.action = action;
        }
    
        private Action Action
        {
            get { return this.action; }
        }
    
        public void Execute()
        {
            this.Action.Invoke();
        }
    }
    
    1. 在您的控件中创建一个List。该集合将保留DeferredAction列表,直到它们可以成功应用(通常在base.OnApplyTemplate()之后)。应用操作后,必须清除集合以避免重复处理。

    2. 在OnValueChanged中,检查你的Part是否为空(可能是),如果是,则将DeferredAction的新实例(OnValueChanged()添加到上一步创建的列表中。注意,OnValueChanged ()是一个双重目的的处理程序,它可以从你的DP值更改处理程序中调用,如果Parts不为null,则可以将其用作可执行的延迟操作。

    3. 在你的OnApplyTemplate循环中你的延迟动作列表(你知道,如果他们在那里,他们还没有被应用)并为每个动作调用Execute。最后清除列表。

    4. 干杯