绑定-回调被调用两次

本文关键字:两次 调用 回调 绑定 | 更新日期: 2023-09-27 18:13:06

我有一个简单的控件的依赖属性,像这样

public class StatusProgress : Control
{
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(StatusProgress),
        new FrameworkPropertyMetadata(null, (d, e) => (d as StatusProgress).TextUpdated(e.OldValue as string)));
    private void TextUpdated(string text)
    {
        Trace.WriteLine("test");
    }
}

然后是viewmodel

public class ViewModelPageAnalyse : ViewModelPageBase
{
    private string _progressText;
    public string ProgressText
    {
        get { return _progressText; }
        set
        {
            _progressText = value;
            OnPropertyChanged(); // base class INotifyPropertyChanged implementation
        }
    }
}

然后有一个用户控件(显示在ContentControl窗口中)。用户控件绑定到带有数据模板的视图模型(也许这很重要)

<DataTemplate DataType="{x:Type local:ViewModelPageAnalyse}">
    <local:UserControlAnalyse/>
</DataTemplate>

这是user control

中的控件
<local:StatusProgress Text="{Binding ProgressText}"/>

现在是有趣的部分。当视图模型中的ProgressText被设置/更改时,属性更改回调被调用两次。我在调试器输出窗口中看到两次"test"

更有趣的是:当视图改变时,由于某种原因,e.NewValue = null再次调用回调,而没有直接将ProgressText设置为null

我已经尝试检查在上升事件之前是否在ProgressText setter中更改了值,尝试设置单向绑定模式,问题仍然存在-回调以相同的值调用两次,调用堆栈看起来相同,但是在wpf中确实有很多调用要真正确定。

虽然双重射击不是一个真正的问题,但它困扰着我。null值的回调是我真正的问题(我认为它们是相关的)。有人知道出了什么问题吗?


找到了第一个问题的原因:它是Content的其他控制。在转换期间,它创建了一个新的Model(因为ContentViewModel),而不是重新分配现有的用户控制。完全是我的错。第二个问题仍然存在,我发现了这个问题(与不适合我的解决方案)。

需要帮助

PropertyChanged回调函数在ContentControl ViewModel被改变时使用默认值调用。

这意味着nullText在我的情况下。有人知道吗?我不明白它为什么叫。我猜它是由DataTemplate经理调用的,如果我可以这样说的话。

绑定-回调被调用两次

尝试改变这一行:

  public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(StatusProgress),
    new FrameworkPropertyMetadata(null, (d, e) => (d as StatusProgress).TextUpdated(e.OldValue as string)));
与这个:

    public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(StatusProgress)
    , new PropertyMetadata(""));