gpt4 book ai didi

c# - 子属性更改时,FreezableCollection 不提供更改通知

转载 作者:太空宇宙 更新时间:2023-11-03 22:16:19 25 4
gpt4 key购买 nike

我有一个 FreezableCollection,我想监视其子属性的更改。这是代码的一个小节:

public class FieldHeading : DependencyObject
{
public static readonly DependencyProperty LayoutProperty = DependencyProperty.Register("Layout", typeof(FieldHeadingLayout), typeof(FieldHeading),
new FrameworkPropertyMetadata(FieldHeadingLayout.Above,
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsParentMeasure));

public FieldHeadingLayout Layout
{
get { return (FieldHeadingLayout) GetValue(LayoutProperty); }
set { SetValue(LayoutProperty, value); }
}

}

public class FieldPanel : FrameworkElement
{
private static readonly DependencyProperty FieldHeadingProperty = DependencyProperty.Register("FieldHeading", typeof(FreezableCollection<FieldHeading>), typeof(FieldPanel),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsParentMeasure |
FrameworkPropertyMetadataOptions.AffectsRender, HeadingChanged));

private static void HeadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("Hello");
}

public FreezableCollection<FieldHeading> FieldHeadings
{
get
{ return (FreezableCollection<FieldHeading>) GetValue(FieldHeadingProperty); }
set { SetValue(FieldHeadingProperty, value);}
}

public FieldPanel()
{
AddVisual(_contentVisual = new DrawingVisual());
FieldHeadings = new FreezableCollection<FieldHeading>();
}
}

然后我们为其中一个 FieldHeadings 的 Layout 分配一个新值,不会生成更改通知。显然我错过了一些重要的东西。永远不会调用 HeadingChanged。

有关 FreezableCollection 的 MSDN 帮助,可在此处找到:FreezableCollection , 状态:

事件已更改... 当 Freezable 或 它包含的对象 被修改时发生。 (继承自 Freezable。)

在此先感谢您的帮助。

~卡梅伦

最佳答案

实际上,您可以做您想做的事。这就是为什么 FreezableCollection<T>存在!您需要做的就是更改 FieldHeadingFreezable 派生而不是 DependencyObject并且对集合中项目的更改将发出相同的更改通知,就好像整个项目已被替换一样。

这是一个非常有用但鲜为人知的 WPF 功能。

From Charles Petzold himself ,

These freezable collection classes fire change notifications whenever items are added to or removed from the collection, of course, but also when a dependency property of any item within the collection changes. This is an extremely powerful mechanism.

这是一个演示如何使用 FreezableCollection<> 的小示例.我在 Visual Studio 中创建了一个新的 WPF 项目。以下是 MainWindow.xaml.cs 的 XAML 及其背后的 C# 代码:

<Window x:Class="FreezableCollection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FreezableCollection"
x:Name="Root"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type local:MyFreezable}">
<CheckBox IsChecked="{Binding IsNice}" Content="Check me!"/>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding ElementName=Root, Path=MyFreezables}" />
</Grid>
</Window>
using System.Windows;

namespace FreezableCollection
{
public partial class MainWindow : Window
{
public static readonly DependencyProperty MyFreezablesProperty =
DependencyProperty.Register("MyFreezables", typeof(MyFreezableCollection), typeof(MainWindow), new FrameworkPropertyMetadata(null, FreezablesChangedCallback));

public MyFreezableCollection MyFreezables
{
get => (MyFreezableCollection)GetValue(MyFreezablesProperty);
set => SetValue(MyFreezablesProperty, value);
}

public MainWindow()
{
InitializeComponent();
MyFreezables = new MyFreezableCollection { new MyFreezable() };
}

private static void FreezablesChangedCallback(object sender, DependencyPropertyChangedEventArgs args)
{
MessageBox.Show("Changed!");
}
}

public class MyFreezableCollection : FreezableCollection<MyFreezable>
{
protected override Freezable CreateInstanceCore() => new MyFreezableCollection();
}

public class MyFreezable : Freezable
{
public static readonly DependencyProperty IsNiceProperty =
DependencyProperty.Register("IsNice", typeof(bool), typeof(MyFreezable), new PropertyMetadata(false));

public bool IsNice
{
get => (bool)GetValue(IsNiceProperty);
set => SetValue(IsNiceProperty, value);
}

protected override Freezable CreateInstanceCore() => new MyFreezable();
}
}

示例显示一个包含单个 CheckBox 的列表.单击它以切换 IsNice数据绑定(bind)中项目的属性 MyFreezableCollection .即使没有向列表中添加任何内容或从列表中删除任何内容,也会调用依赖属性更改回调

关于c# - 子属性更改时,FreezableCollection 不提供更改通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5045366/

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