依赖属性收到xaml更改时的回调

Noe*_*mer 2 c# wpf xaml dependency-properties

当我IsClosed在运行时设置值时,OnIsClosedChanged()称为罚款.但是,Designer会设置属性的值,但不会调用OnIsClosedChanged().

public static DependencyProperty IsClosedProperty = DependencyProperty.Register("IsClosed", typeof(bool), typeof(GroupBox), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));

public bool IsClosed {
    get {
        return (bool)this.GetValue(IsClosedProperty);
    }
    set {
        if ((bool)this.GetValue(IsClosedProperty) == value)
            return;

        this.SetValue(IsClosedProperty, value);
        OnIsClosedChanged();
    }
}



private void OnIsClosedChanged() {
    _rowDefContent.Height = new GridLength((IsClosed ? 0 : 1), GridUnitType.Star);
}
Run Code Online (Sandbox Code Playgroud)

显然IsClosed,Designer不会对其进行修改,只会IsClosedProperty接收xaml更改.
我的问题是:如何IsClosed在Designer中修改了值后运行.或者至少为非运行时更改添加一些逻辑.

Cle*_*ens 10

您必须使用属性元数据注册PropertyChangedCallback.

原因是在XAML中设置的依赖项属性或绑定或某些其他源不设置CLR包装器(setter方法).原因在MSDN上的XAML加载和依赖属性文章中进行了解释:

出于实现原因,将属性标识为依赖项属性并访问属性系统SetValue方法来设置它,而不是使用属性包装器及其setter,计算成本更低.

...

由于属性设置的XAML处理器行为的当前WPF实现完全绕过包装器,因此不应将任何其他逻辑放入自定义依赖项属性的包装器的集定义中.如果将这样的逻辑放在set定义中,那么当在XAML中而不是在代码中设置属性时,将不会执行逻辑.

您的代码应如下所示:

public static readonly DependencyProperty IsClosedProperty =
    DependencyProperty.Register(
        "IsClosed", typeof(bool), typeof(GroupBox),
        new FrameworkPropertyMetadata(false,
            FrameworkPropertyMetadataOptions.AffectsRender,
            (o, e) => ((GroupBox)o).OnIsClosedChanged()));

public bool IsClosed
{
    get { return (bool)GetValue(IsClosedProperty); }
    set { SetValue(IsClosedProperty, value); }
}

private void OnIsClosedChanged()
{
    _rowDefContent.Height = new GridLength((IsClosed ? 0 : 1), GridUnitType.Star);
}
Run Code Online (Sandbox Code Playgroud)