8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

当依赖属性收到 xaml 改变时回调

Jonathan Gilbert 2月前

37 0

当我在运行时设置 IsClosed 的值时,OnIsClosedChanged() 被正确调用。但是,Designer 设置了属性的值,但没有调用 OnIsClosedChanged()。 public static

在运行时 IsClosed 设置的值时 OnIsClosedChanged() 调用正常。但是,设计器设置了属性的值,但没有调用 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);
}

显然 IsClosed 没有被设计师修改,只 IsClosedProperty 接收xaml的改变。
在 Designer 中修改值后 IsClosed 如何运行

帖子版权声明 1、本帖标题:当依赖属性收到 xaml 改变时回调
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Jonathan Gilbert在本站《wpf》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 您是否尝试过使用 ValidateValueCallback?使用 DependencyProperty.Register 的重载方法

  • 我以前也犯过同样的错误。依赖属性是深层次的东西。该属性只向您公开它,但 WPF 不会使用您的属性(您可以删除它)。@AlexK,评论是正确的(这可能是答案),使用回调来在以下情况下收到通知

  • 您必须 使用属性元数据 PropertyChangedCallback

    原因是在 XAML 中或通过绑定或其他来源设置的依赖项属性不会调用 CLR 包装器(setter 方法)。MSDN XAML 加载和依赖项属性 文章解释了原因:

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

    ...

    由于当前 WPF 实现的 XAML 处理器属性设置行为完全绕过了包装器,因此您不应将任何其他逻辑放入自定义依赖属性的包装器的设置定义中。如果您将此类逻辑放入设置定义中,则在 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);
    }
    
  • 现在我自己找到了答案。ValidateValueCallback 非常接近!(正如 Alex K 指出的那样)但它是一种静态方法,我没有获得对已更改实例的任何引用。关键是在 FrameworkPropertyMetadata 中使用 PropertyChangedCallback,它也是传递给 Property.Register 方法的参数。
    看:

    public static DependencyProperty IsClosedProperty = DependencyProperty.Register("IsClosed", typeof(bool), typeof(GroupBox), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnIsClosedChangedPCC)));
    
            public bool IsClosed {
                get {
                    return (bool)this.GetValue(IsClosedProperty);
                }
                set {
                    this.SetValue(IsClosedProperty, value);
                    OnIsClosedChanged();
                }
            }
    
    
    
            private static void OnIsClosedChangedPCC(DependencyObject d, DependencyPropertyChangedEventArgs e) {
                GroupBox current = (GroupBox)d;
                current.IsClosed = current.IsClosed;
            }
    
    
    
            private void OnIsClosedChanged() {
                _rowDefContent.Height = new GridLength((IsClosed ? 0 : 1), GridUnitType.Star);
            }
    

    现在确实会重新设置 IsClosedValue 触发 OnIsClosedChanged 运行的。
    谢谢你们的帮助!

  • 最后一步:从属性设置器方法中删除 OnIsClosedChanged()。并且不要在 PropertyChangedCallback 中再次设置该属性。这没有意义。

返回
作者最近主题: