【问题标题】:NotifyPropertyChanged isn't updating DependencyProperty in CustomControlNotifyPropertyChanged 没有更新 CustomControl 中的 DependencyProperty
【发布时间】:2019-09-07 14:43:26
【问题描述】:

我用 DP Threshold 制作了一个 CustomControl,如下所示:

public class SymbolControl : Control
{
    public static readonly DependencyProperty ThresholdProperty = DependencyProperty.Register("Threshold", typeof(IThreshold<SolidColorBrush>), typeof(SymbolControl));

    public IThreshold<SolidColorBrush> Threshold
    {
        get { return (IThreshold<SolidColorBrush>)GetValue(ThresholdProperty); }
        set { SetValue(ThresholdProperty, value);  }
    }
...
}

这里是自定义控件的xaml中使用Property的地方:

...
        <Border.Background>
            <MultiBinding Converter="{StaticResource ThreshholdToReturnValueConverter}" NotifyOnTargetUpdated="True" >
                <Binding Path="Threshold" RelativeSource="{RelativeSource TemplatedParent}" NotifyOnTargetUpdated="True" />
                <Binding Path="SymbolValue" RelativeSource="{RelativeSource TemplatedParent}" NotifyOnTargetUpdated="True" />
                <Binding Path="DefaultBackground" RelativeSource="{RelativeSource TemplatedParent}" NotifyOnTargetUpdated="True" />
            </MultiBinding>
        </Border.Background>
...

下面是 CustomControl 的使用方法:

<controls:SymbolControl ... Threshold="{Binding Threshold, NotifyOnTargetUpdated=True, Converter={StaticResource DummyConverter}}" .../>

当我调用NotifyPropertyChanged(nameof(Threshold)) 时,CustomControl 没有更新。

但是,当自定义控件被实例化并且此断点在我调用NotifyPropertyChanged(nameof(Threshold)) 时触发时,我在阈值绑定中放置了一个带有断点的虚拟转换器,所以看起来绑定没有更新目标?

我还尝试为 DP ThresholdProperty 添加一个 PropertyChangedCallback 并带有一个断点,该断点仅在第一次实例化原始属性时触发。

我还发现在 ViewModel 中执行此操作会导致自定义控件更新:

var temp = Threshold;
Threshold = null;
Threshold = temp;

我在网上做了很多搜索,但没有运气,你知道问题出在哪里吗?

【问题讨论】:

  • Threshold 依赖属性会忽略任何更新,只要您不将其值替换为新的 IThreshold&lt;SolidColorBrush&gt; 实例,即 {Binding Threshold} 提供不同的对象(或 null)。这是设计使然。
  • @Clemens 哦,我不知道,有没有办法解决这个问题?
  • 是的,做你已经做过的,即设置一个临时的空值。
  • 问题是如果IThreshold&lt;SolidColorBrush&gt; 实例中的某个属性发生更改,我找不到执行那段代码的方法,我已尝试将其添加到PropertyChanged_threshold.PropertyChanged += Threshold_PropertyChanged; 之类的事件(void Threshold_PropertyChanged(object sender, PropertyChangedEventArgs e) 将其临时设置为 null)在 setter 中,但这不起作用,因为它将自己分配为 null 所以最后一行 (Threshold = temp;) 不会执行
  • 您可以更改 MultiBinding(及其转换器),使其绑定到阈值的各个属性,例如&lt;Binding Path="Threshold.SomeValue" .../&gt;。当然这些属性也必须触发 INotifyPropertyChanged 接口的 PropertyChanged 事件。

标签: c# wpf custom-controls dependency-properties inotifypropertychanged


【解决方案1】:

我发现了另一种解决方法,因为我无法使用问题中给出的其他解决方法:

我将代码添加到Threshold.cs

public Threshold : IThreshold<SolidColorBrush>, INotifyPropertyChanged
{
...
    public Threshold()
    {
        ...
        this.PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) { if (e.PropertyName != nameof(WorkAround)) { NotifyPropertyChanged(nameof(WorkAround)); } };
    }
...
public bool WorkAround { set; get; }
}

在自定义控件的xaml 中,我将第四个绑定添加到MultiBinding

...
        <Border.Background>
            <MultiBinding Converter="{StaticResource ThreshholdToReturnValueConverter}" NotifyOnTargetUpdated="True" >
                <Binding Path="Threshold" RelativeSource="{RelativeSource TemplatedParent}" NotifyOnTargetUpdated="True" />
                <Binding Path="SymbolValue" RelativeSource="{RelativeSource TemplatedParent}" NotifyOnTargetUpdated="True" />
                <Binding Path="DefaultBackground" RelativeSource="{RelativeSource TemplatedParent}" NotifyOnTargetUpdated="True" />
                <Binding Path="Threshold.WorkAround" RelativeSource="{RelativeSource TemplatedParent}" NotifyOnTargetUpdated="True" />
            </MultiBinding>
        </Border.Background>
...

但是这个解决方法并不理想,所以我不会接受它,如果有人找到更好的解决方案,请告诉我:)

【讨论】:

    猜你喜欢
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 2013-11-12
    相关资源
    最近更新 更多