【问题标题】:Set a dependency property from a method which calls a property changed callback从调用属性更改回调的方法中设置依赖属性
【发布时间】:2012-06-28 20:17:44
【问题描述】:

我的 WPF 控件有一个奇怪的问题。基本上我有一个控件,它在我的主要内容前面呈现模态内容。我的控制是对here 显示的答案的修改。

我有一个名为IsShownBool 依赖属性,用于隐藏/显示模式内容。属性定义如下:

public static readonly DependencyProperty IsShownProperty =
    = DependencyProperty.Register("IsShown",
    typeof(bool), 
    typeof(ModalContentControl), 
    new UIPropertyMetadata(false, IsShownChangedCallback));

它有一个标准的 .Net 属性包装器,如下所示:

public bool IsShown
{
    get { return (bool)GetValue(IsShownProperty); }
    set { SetValue(IsShownProperty, value); }
}

属性更改回调如下所示:

private static void IsShownChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ModalContentControl control = (ModalContentControl)d;

    if ((bool)e.NewValue == true)
    {
        control.ShowModalContent();
    }
    else
    {
        control.HideModalContent();
    }
}

ShowModalContentHideModalContent 方法分别包含显示和隐藏模态内容的逻辑。

我的窗口中有这个控件,IsShown 属性绑定到我的 viewModel。我可以按下一个按钮,该按钮调用一个命令,该命令更改绑定到我的控件的IsShown 属性的布尔属性。模态内容按预期显示和隐藏。

我的问题来自 ShowModalContentHideModalContent 方法是公共的,因此可以从代码中调用它们。例如,我想做的是调用ShowModalContent,当我查询IsShown 属性时,它应该报告正确的值(在这种情况下为true)。如果我使用的是常规属性,我将有一个 Bool 类型的支持字段,它将在方法中更新。然后该字段将由属性 get 语句返回。

但是因为我的属性是依赖属性,所以我无权访问支持字段。我可以从该方法更新值的唯一方法是通过 .net 包装器设置依赖属性,但这会阻止我的控制工作(一旦显示内容,我就无法再次摆脱它)。

我认为这种行为可能是由在方法中设置 IsShown 属性引起的,该方法调用属性更改的回调,它设置了调用的 IsShown 属性。但我记得在某处读过 WPF 可以防止这种情况.

那么我该如何解决这个问题,以便我的布尔依赖属性报告正确的值?

【问题讨论】:

    标签: wpf dependency-properties


    【解决方案1】:

    经过一番思考(以及一些运气),我设法找出了问题所在。为了让它发挥作用,我需要改变两件事。

    第一个问题是ShowModalContentHideModalContent 方法做了两件事。

    1. 设置IsShown 属性。
    2. 正在更新控件的状态。

    这是一个问题,因为更改IsShown 属性会调用IsChangedCallback,后者调用ShowModalContentHideModalContent 方法,然后更改IsShown 属性。我认为WPF 阻止了无限循环的发生,但即使尝试通过缓存值在代码中管理它也是一个令人头疼的问题。

    当我意识到公共方法应该做的唯一事情是设置属性时,我的灵感来了。我的公共方法现在看起来像这样:

    public void ShowModalContent()
    {
        IsShown = true;
    }
    
    public void HideModalContent()
    {
        IsShown = false;
    }
    

    这会触发属性更改回调,从而更新控件的状态。

    我的第二个灵感时刻是当我意识到我的 ViewModel 没有准确地反映 IsShown 属性的状态时,这是由于默认依赖属性绑定模式显然是 OneWay 造成的。我只是将我的DependencyProperty 定义绑定模式更新为BindsTwoWayByDefault,现在一切正常。

    IsShownProperty = DependencyProperty.Register("IsShown",
        typeof(bool), typeof(ModalContentControl), 
        new FrameworkPropertyMetadata(false, 
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
            IsShownChangedCallback));
    

    【讨论】:

      猜你喜欢
      • 2010-11-08
      • 1970-01-01
      • 2014-06-14
      • 1970-01-01
      • 2015-04-02
      相关资源
      最近更新 更多