类的作用只是把散落在程序中的变量和函数进行归档封装并控制对它们的访问。被封装在类里的变量称为字段(Field),表示的是类或实例的状态;被封装在类里的函数称为方法(Method),表示类或实例的功能。是否使用static关键字来修饰字段或方法则取决于字段或方法是对类有意义还是对类的实例有意义。
C#语言规定:对类有意义的字段和方法使用static关键字修饰,称为静态成员,通过类名加访问修饰符(即“.”操作符)访问它们;对类的实例有意义的字段和方法不加static关键字,称为非静态成员或实例成员。
静态字段在内存中只有一个拷贝,非静态字段则是每个实例拥有一个拷贝,无论方法是否为静态,在内存中都只有一份拷贝,区别只是能通过类名来访问存放指令的内存还是通过实例名来访问存放指令的内存。
.NET Framework中的属性又称为CLR属性,既可以说CLR属性是private字段的安全访问包装,也可说一个private字段在后台支持(back)一个CLR属性。
C#代码中的属性的编译结果是两个方法,并不会增加内存的负担。
依赖属性就是一种可以自己没有值,并能通过使用Binding从数据源获得值得属性。拥有依赖属性的对象被称为“依赖对象”。
WPF允许对象在被创建时并不包含用于存储对象的空间(既字段所占有的空间),只保留在需要用到数据时能够获得默认值、借用其他对象数据或实时分配空间的能力--这种对象就称为依赖对象(Dependency Object),而它这种实时获取数据的能力则依靠依赖属性(Dependency Property)来实现。在WPF开发中,必须使用依赖对象作为依赖属性的宿主。
WPF所有UI控件都是依赖对象。
自定义Dependency Property的宿主一定是Dependency Object的派生类。Dependency Property实例的声明特点:引用变量由public static readonly三个修饰符修饰,实例使用DependencyProperty.Register方法生成。
依赖对象是作为数据的目标而存在的,当为依赖对象的依赖属性添加了CLR属性包装时,就相当于为依赖对象准备了用于暴露数据的Binding Path,也就是说,依赖对象具备了扮演数据源和数据目标双重角色的能力。值得注意的是,当依赖属性的值发生改变时,与之关联的Binding对象依然可以得到通知,依赖属性默认带有这种功能。
XAML:
<StackPanel Background="LightBlue">
<TextBox x:Name="textBox1" BorderBrush="Black" Margin="5"/>
<TextBox x:Name="textBox2" BorderBrush="Black" Margin="5,0"/>
<Button Content="OK" Margin="5" Click="Button_Click"/>
</StackPanel>
C#代码:
public class Student : DependencyObject
{
public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name",typeof(string),typeof(Student));
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty,value); }
}
public BindingExpressionBase SetBinding(DependencyProperty dp,BindingBase binding)
{
return BindingOperations.SetBinding(this,dp,binding);
}
}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
Student stu;
public MainWindow()
{
InitializeComponent();
stu = new Student(); stu.SetBinding(Student.NameProperty,new Binding("Text") { Source = this.textBox1 }); textBox2.SetBinding(TextBox.TextProperty,new Binding("Name") { Source = stu }); } private void Button_Click(object sender,RoutedEventArgs e) { /*Student stu = new Student(); stu.Name = this.textBox1.Text; this.textBox2.Text = stu.Name;*/ }