Freezable 对象(WPF)

# Freezable 对象(WPF) #

> Freezable 继承自 DependencyObject,同时添加了 Freezable 方法,用于冻结对象。

---

## 冻结对象 ##

以此为示例

```ruby
    def say_hi
        print "hello world" 
    end
```
```cs
    namespace ConsoleApplication2
    {
        public class Person : Freezable
        {
            public string Name
            {
                 get { return (string)GetValue(NameProperty); }
	         set { SetValue(NameProperty, value); }
	     }
	
	     public static readonly DependencyProperty NameProperty =
	     DependencyProperty.Register("Name", typeof(string), typeof(Person), new UIPropertyMetadata(0));
	
	    protected override Freezable CreateInstanceCore()
	    {
	        throw new NotImplementedException();
	    }
	
        }
    }
```

现实生活中,人的名字是不可以随便更改的,当名字定下来以后,就把该对象冻结了,那么就不能再修改此对象的属性了,如下

```cs
	namespace ConsoleApplication2
	{
	    class Program
	    {
	        static void Main(string[] args)
	        {
	            Person person = new Person();
	            person.Name = "Chang weihua";
	            person.Freeze();
	
	            //不能再赋值了
	            person.Name = "Changweihua 2013";
	
	            Console.ReadKey(true);
	        }
	    }
	}
```

## 依赖对象与冻结 ##

当调用 Freeze 方法后,DependencyObject 将会成为一个密封类(Sealed)。一旦 DependencyObject 成为密封类,那么内部将无法修改依赖项属性,这也意味着如果定义普通的 CLR 属性则没有这个问题。

## 冻结状态 ##

1. 在冻结之前,需要知道该对象是否已经冻结(IsFrozen),当冻结之后, IsFrozen 为 True。
2. 即使继承了 Freezable 的对象,并非随时都可以冻结,在调用 Freeze 方法之前,需要查看 CanFrozen 属性判断该对象是否可以冻结(如果该对象可以冻结,即使调用 Freeze 方法后,该属性还是 True),否则会报错。
3. 冻结后的对象无法解冻,必须采用克隆的方法创建一个新对象。

## 无法冻结的情况 ##

1. 绑定时
	当一个 DependencyProperty 对象其中有 DependencyProperty 有绑定时,无法冻结,当 DependencyProperty 接触绑定之后可以(如果进行了绑定就意味着值可能会被修改,那么该对象就是被冻结了的了)
	
```cs
		namespace ConsoleApplication2
		{
		    class Program
		    {
		        static void Main(string[] args)
		        {
		            Person person = new Person();
		
		            BindingOperations.SetBinding(person, Person.NameProperty, new Binding("Name") { Source = person });
		            if (person.CanFreeze)
		                person.Freeze();
		
		            person.Name = "Chang weihua";
		
		            Console.WriteLine(person.Name);
		
		            //解除绑定
		            BindingOperations.ClearBinding(person, Person.NameProperty);
		            //解除绑定之后可以赋值
		            person.Name = "Changweihua 2012";
		            Console.WriteLine(person.Name);
		
		            if (person.CanFreeze)
		                person.Freeze();
		
		            //不能再赋值了
		            //person.Name = "Changweihua 2013";
		            //Console.WriteLine(person.Name);
		
		            Console.ReadKey(true);
		        }
		    }
		}
```

2. Freezable 中定义的 DependencyProperty 属性类型必须是值类型或者是 Freezable 类型。
	比如在其中定义一个 Button 类型(非 Freezable 类型)的 DependencyProperty,当其中有值时,则无法冻结。

## Freezable 特性 ##

1. 可子属性变更通知
2. 克隆

	如果定义的属性均为依赖属性,那么克隆就会变得很简单,调用父类方法就行,如

```cs
		public SolidColorBrush Clone()
		{
			return (SolidColorBrush)base.Clone();
		}
```

3. 冻结之后的对象将与 UI 线程分离

	其会将内部的 Dispatcher 属性设置为空,就是需要注意的。

	总结:当对象不需要发生改变时,则冻结该对象,减少对象监听,提示性能
posted @ 2013-07-07 14:05  常伟华  阅读(1047)  评论(0编辑  收藏