myBrush.Freeze();
二、可冻结判断
若要使 Freezable 其成为不可修改的,请调用其 Freeze 方法。 冻结包含可冻结对象的对象时,这些对象也会被冻结。 例如,如果冻结 PathGeometry ,则它包含的图形和段也将被冻结。
如果满足以下任一条件,则 无法 冻结可冻结的:
它具有动画或数据绑定属性。
它包含动态资源设置的属性。 (有关动态资源的详细信息,请参阅 XAML 资源 。 )
它包含 Freezable 无法冻结的子对象。
如果这些条件为 false,并且你不打算修改,则 Freezable 应该冻结它以获得前面所述的性能优势。
调用可冻结的方法后 Freeze ,将无法再对其进行修改。 尝试修改冻结对象将导致 InvalidOperationException 引发。 下面的代码引发异常,因为我们尝试在冻结画笔之后修改画笔。
若要避免引发此异常,可以使用 IsFrozen 方法来确定是否 Freezable 已冻结。
Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
if (myBrush.CanFreeze)
// Makes the brush unmodifiable.
myBrush.Freeze();
myButton.Background = myBrush;
if (myBrush.IsFrozen) // Evaluates to true.
// If the brush is frozen, create a clone and
// modify the clone.
SolidColorBrush myBrushClone = myBrush.Clone();
myBrushClone.Color = Colors.Red;
myButton.Background = myBrushClone;
// If the brush is not frozen,
// it can be modified directly.
myBrush.Color = Colors.Red;
三、标签语言修改
若要冻结 Freezable 在标记中声明的对象,请使用 PresentationOptions:Freeze 特性。 在下面的示例中,将 SolidColorBrush 声明为页资源并冻结。 然后,将使用它来设置按钮的背景。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions">
<Page.Resources>
<!-- This resource is frozen. -->
<SolidColorBrush
x:Key="MyBrush"
PresentationOptions:Freeze="True"
Color="Red" />
</Page.Resources>
<StackPanel>
<Button Content="A Button"
Background="{StaticResource MyBrush}">
</Button>
</StackPanel>
</Page>
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions"
若要使用 Freeze 属性,必须映射到表示选项命名空间: http://schemas.microsoft.com/winfx/2006/xaml/presentation/options 。 PresentationOptions 建议用于映射此命名空间的前缀:
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
由于并非所有 XAML 读取器都能识别此特性,因此建议使用 mc:可忽略属性 将属性标记 Presentation:Freeze 为可忽略:
四、创建自己的可冻结对象
派生自的类具有 Freezable 以下功能。
特殊状态:只读 (冻结) 和可写状态。
线程安全:冻结 Freezable 可以在线程之间共享。
详细更改通知:与其他不同 DependencyObject ,可冻结对象会在子属性值更改时提供更改通知。
轻松克隆:可冻结的类已经实现了几种生成深层克隆的方法。
Freezable是的一种类型 DependencyObject ,因此使用了依赖属性系统。 类属性不一定是依赖属性,但使用依赖属性将减少您必须编写的代码量,因为 Freezable 该类是使用依赖属性设计的。 有关依赖属性系统的详细信息,请参阅 依赖属性概述。
每个 Freezable 子类必须重写 CreateInstanceCore 方法。 如果你的类对所有数据使用依赖属性,则你已完成。
如果类包含非依赖属性数据成员,还必须重写以下方法:
CloneCore
CloneCurrentValueCore
GetAsFrozenCore
GetCurrentValueAsFrozenCore
FreezeCore
还必须遵守以下规则,以便访问和写入不是依赖属性的数据成员:
在读取非依赖属性数据成员的任何 API 的开头,调用 ReadPreamble 方法。
在写入非依赖属性数据成员的任何 API 的开头,请调用 WritePreamble 方法。 (WritePreamble 在 API 中调用后, ReadPreamble 如果还读取非依赖属性数据成员,则无需额外调用。 )
WritePostscript在退出写入非依赖属性数据成员的方法之前调用方法。
如果类包含非依赖属性数据成员 DependencyObject (这些对象是对象),则在 OnFreezablePropertyChanged 每次更改其值时,您还必须调用方法,即使您要将成员设置为 null
。