WPF CustomControl:在PropertyChangedCallback之后调用的OnApplyTemplate

8 wpf custom-controls propertychanged

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

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

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

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

小智 7

这就是我们所做的 - 不解决原则中的问题,但提供了明确的解决方法.

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

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

这是我使用的:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 在您的控件中创建一个List.该集合将保留DeferredAction列表,直到它们可以成功应用(通常在base.OnApplyTemplate()之后).应用操作后,必须清除集合以避免双重处理.

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

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

干杯