WPF 之 依赖属性与附加属性(五) (2)

​ 我们先把该依赖属性作为数据目标获取第一个 TextBox 的 Text 属性,然后把自己的 DisplayText 依赖属性的值作为第二个 TextBox 的 Text 属性的数据源:

<StackPanel> <TextBox Margin="5" x:Name="t1"></TextBox> <!--自定义依赖属性作为 Target--> <local:MorTextBox x:Name="t2" Visibility="Collapsed" DipalyText="{Binding ElementName=t1,Path=Text,UpdateSourceTrigger=PropertyChanged}"></local:MorTextBox> <!--自定义依赖属性作为 Source--> <local:MorTextBox Margin="5" Text="{Binding ElementName=t2,Path=DipalyText,UpdateSourceTrigger=PropertyChanged}"></local:MorTextBox> </StackPanel>

​ 当我们运行程序后,第二个 TextBox 的数值随着第一个 TextBox 数值的改变而改变。

三、附加属性(Attached Properties)

​ 实际开发中,我们会经常遇到这样的情况,一个人在学校的时候需要记录班级等信息,在公司需要记录职业等信息,那么如果我们在设计 Human 类的时候,在类里面直接定义 Grade、Position 属性合适吗?

​ 显然不合适!首先,当我们在学校上学的时候完全用不到公司等信息,那么Position 所占的内存就被浪费了。为了解决此问题,我们首先想到依赖属性,但解决了内存浪费问题,还存在一个问题,即一旦流程改变,那么 Human 类就需要做出改动,例如:当我们乘车的时候,有车次信息;去医院看病的时候,有排号信息等。这意味着应用场景的不断变化,导致我们所属的信息不断发生变化。为了解决此问题,.NET 推出了附加属性(Attached Properties)。

附加属性(Attached Properties)是说一个属性本来不属于某个对象,但由于某种需求而被后来附加上。也就是说把对象放入一个特定环境后对象才具有的属性(表现出来就是被环境赋予的某种属性)。上述例子,我们可以使用附加属性去解决这个问题(添加附加属性时,可以在 Visual studio 中输入 "propa" 然后按 Tab 键快捷生成):

class Human : DependencyObject { public string Name { get; set; } public int Age { get; set; } } class School : DependencyObject { public static string GetGrade(DependencyObject obj) { return (string) obj.GetValue(GradeProperty); } public static void SetGrade(DependencyObject obj, string value) { obj.SetValue(GradeProperty, value); } // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... public static readonly DependencyProperty GradeProperty = DependencyProperty.RegisterAttached("Grade", typeof(string), typeof(School), new PropertyMetadata("")); } class Company : DependencyObject { public static string GetPosition(DependencyObject obj) { return (string) obj.GetValue(PositionProperty); } public static void SetPosition(DependencyObject obj, string value) { obj.SetValue(PositionProperty, value); } // Using a DependencyProperty as the backing store for Position. This enables animation, styling, binding, etc... public static readonly DependencyProperty PositionProperty = DependencyProperty.RegisterAttached("PPosition", typeof(string), typeof(Company), new PropertyMetadata("")); }

​ 使用依赖属性的方式如下:

// Attached Properties { Human human0 = new Human() { Name = "John", Age = 10, }; School.SetGrade(human0, "四年级二班"); Human human1 = new Human() { Name = "Andy", Age = 26, }; Company.SetPosition(human1, "软件工程师"); Human human2 = new Human() { Name = "Kolity", Age = 25, }; Company.SetPosition(human2, "产品经理"); TextBoxAttached.Text += $"{human0.Name},{human0.Age},{School.GetGrade(human0)}\r\n"; TextBoxAttached.Text += $"{human1.Name},{human1.Age},{Company.GetPosition(human1)}\r\n"; TextBoxAttached.Text += $"{human2.Name},{human2.Age},{Company.GetPosition(human2)}\r\n"; }

​ 输出结果,如下所示:

John,10,四年级二班 Andy,26,软件工程师 Kolity,25,产品经理

​ 从附加属性的实现中,我们可以看出附加属性(Attached Properties)的本质就是依赖属性(Dependency Property)。附加属性通过声明与依赖属性相关的 Get 与 Set 方法实现寄宿在宿主类(例如:Human)上,这意味宿主类也必须实现 DependencyObject 类。

​ 其实,WPF 控件的布局控件的许多属性就为附加属性,例如:当把一个 TextBox 放入 Grid中时,对于 TextBox 而言我们可以使用 Grid 的 Row 和 Column 属性,如下:

<Grid > <TextBox Grid.Row="0" Grid.Column="0"></TextBox> </Grid>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfwjg.html