WPF CustomControl:在PropertyChangedCallback之后调用OnApplyTemplate [英] WPF CustomControl: OnApplyTemplate called after PropertyChangedCallback

查看:219
本文介绍了WPF CustomControl:在PropertyChangedCallback之后调用OnApplyTemplate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a WPF CustomControl that has a dependency property with PropertyChangedCallback. In that Callback method I try to set values on some of the control's parts that I retrieve from OnApplyMethod using the GetTemplateChild() method.

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

The problem is that the PropertyChangedCallback is (on some systems) called before OnApplyTemplate so the control parts are still null.

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

The workaround I'm currently using is to save e.NewValue from the PropertyChangedCallback to a member variable and then call SetValue(dp, _savedValue) in OnApplyTemplate().

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

What is the proper way to deal with this problem or am I already using the best solution?

推荐答案

这就是我们要做的-不能解决原则中的问题,但提供了解决它的清晰方法.

that's what we do - doesn't solve the problme in priciple but provides with a clear way to fix it.

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

  1. Create a handler for the DP value changed event, let it be OnValueChanged().Generally no paramters needed as you know which DP is changed and can always obtain its current value.

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

Create a class/struct called DeferredAction with the constructor, accepting System.Action (that's going to be a ref to your OnValueChanged()). The class will have a property Action and a method, called 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();
    }
}

  1. 在您的控件中创建一个列表.该集合将保留DeferredAction的列表,直到可以成功应用它们为止(通常在base.OnApplyTemplate()之后).一旦应用了操作,就必须清除集合以避免重复处理.

  1. In your control create a List. The collection will keep the list of DeferredAction's until they can be successfully applied (typically after base.OnApplyTemplate()). Once actions are applied the collection has to be cleared to avoid double processing.

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

Within OnValueChanged do check if your Part(s) is not null (which it likely is) and if so add a new instance of DeferredAction(OnValueChanged() to the list created at a previous step. Note, OnValueChanged() is a dual purpose handler it can be called right from your DP value changed handler, if Parts aren't null, alterantively it's used as an executable deferred action.

在您的OnApplyTemplate中,循环遍历您的延迟操作列表(您知道,如果存在,则尚未应用),并为每个调用Execute.清除列表末尾.

Within you OnApplyTemplate loop through your deferred actions list (you know, if they're there, they haven't been applied) and call Execute for each of them. Clear the list at the end.

欢呼

这篇关于WPF CustomControl:在PropertyChangedCallback之后调用OnApplyTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆