gpt4 book ai didi

c# - WPF:PropertyChangedCallback 只触发一次

转载 作者:太空狗 更新时间:2023-10-29 17:34:31 24 4
gpt4 key购买 nike

我有一个用户控件,它公开了一个名为 VisibileItems 的 DependencyProperty每次更新该属性时,我都需要触发另一个事件。为此,我添加了一个带有 PropertyChangedCallback 事件的 FrameworkPropertyMetadata。

出于某种原因,此事件仅被调用一次,并且在 VisibleItems 下次更改时不会触发。

XAML:

<cc:MyFilterList VisibleItems="{Binding CurrentTables}"  />

CurrentTables 是 MyViewModel 上的 DependencyProperty。 CurrentTables 经常更改。我可以将另一个 WPF 控件绑定(bind)到 CurrentTables,并且我看到了 UI 中的更改。

这是我使用 PropertyChangedCallback 连接 VisibleItems 的方式

public static readonly DependencyProperty VisibleItemsProperty =
DependencyProperty.Register(
"VisibleItems",
typeof(IList),
typeof(MyFilterList),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(VisiblePropertyChanged))

);

public IList VisibleItems {
get { return (IList)GetValue(VisibleItemsProperty); }
set { SetValue(VisibleItemsProperty, value); }
}

通过进入 VisiblePropertyChanged,我可以看到它在第一次设置 CurrentTables 时被触发。但不是随后的时间。

更新

由于你们中的一些人质疑 CurrentTables 的修改方式,它在更改时完全重新分配:

OnDBChange()...
CurrentTables = new List<string>(MainDatabaseDataAdapter.GetTables(this.SelectedServer, this.SelectedDatabase));

此行在每次更改时都会被调用,但我的 VisiblePropertyChanged 处理程序仅在第一次被调用。

更新

如果我直接分配 VisibleItems,处理程序每​​次都会被调用!

TestFilterList.VisibleItems = new List<string>( Enumerable.Range(1, DateTime.Now.Second).ToList().Select(s => s.ToString()).ToList() );

因此,问题似乎源于 DependencyProperty (VisibleItems) 正在监视另一个 DependencyProperty (CurrentTables)。绑定(bind)以某种方式适用于第一个属性更改,但不适用于后续属性更改?尝试按照你们中的某些人的建议使用 snoop 检查此问题。

最佳答案

您是否正在为也具有 OneWay 绑定(bind)的依赖属性设置“本地”值(即直接分配给依赖属性 setter )?如果是这样,设置本地值将删除绑定(bind),如 the MSDN dependency property overview: 中所述

Bindings are treated as a local value, which means that if you set another local value, you will eliminate the binding.

当被要求将本地值存储在依赖属性上时,依赖属性机制无能为力。它无法通过绑定(bind)发送值,因为绑定(bind)“指向”错误的方式。设置为本地值后,它不再显示从绑定(bind)中获得的值。因为它不再显示绑定(bind)的值,所以它删除了绑定(bind)。

绑定(bind)消失后,当绑定(bind)的源属性更改其值时,将不再调用 PropertyChangedCallback。这可能就是未调用回调的原因。

如果您将绑定(bind)设置为TwoWay,则绑定(bind)系统确实有地方可以存储您设置的“本地”值:在绑定(bind)的源属性中。在这种情况下,不需要消除绑定(bind),因为依赖属性机制可以将值存储在源属性中。

这种情况不会导致堆栈溢出,因为会发生以下情况:

  • 依赖属性接收“本地”值。
  • 依赖属性机制将值“向后”发送到绑定(bind)到源属性,
  • 源属性设置属性值并触发 PropertyChanged,
  • 依赖属性机制接收到 PropertyChanged 事件,检查源属性的新值,发现它没有改变,什么也不做。

这里的关键点是,如果您为 其值未更改的属性触发 PropertyChanged 事件,则任何 PropertyChangedCallback绑定(bind)到您的属性的依赖属性将不会被调用。

为简单起见,我忽略了上面的 IValueConverter。如果您有转换器,请确保它在两个方向上都能正确转换值。我还假设另一端的属性是实现 INotifyPropertyChanged 的对象的 View 模型属性。在绑定(bind)的源端可能有另一个依赖属性。依赖属性机制也可以处理这个问题。

碰巧,WPF(和 Silverlight)不包含对堆栈溢出的检测。如果在 PropertyChangedCallback 中,您将依赖属性的值设置为其新值(例如,通过递增整数值属性或将字符串附加到字符串值属性),您会出现堆栈溢出。

关于c# - WPF:PropertyChangedCallback 只触发一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5795770/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com