XAML代码是如此简单,简单就那么一句话。这可不是吾等C#程序员、刨根问底之徒可以善罢甘休的!
形象地讲,Binding就像一个盒子,盒子里装了一些机关用于过滤和控制数据,盒子两端各接着一根管子,管子是由管壳和管芯构成的,看上去就像下面的图:
当脑子里有了这样一个形象之后,遵循下面的步骤就OK了:
- Source:确定哪个对象作为数据源
- Target:确定哪个对象作为目标
- Binding:声明一个Binding实例
- 把一根管子接到Source上并把管芯插在Source的Path上
- 把另一根管子接到Target上并把管芯插在Target的联动属性上
我猜你可能会问:“那个D.P.是什么呀?”
D.P.的全称是“Dependency Property”,直译过来就是“依赖式属性”,意思是说它自己本身是没有值的,它的值是“依赖”在其它对象的属性值上、通过Binding的传递和转换而得来的。表现在例子里,它就是Target上的被数据所驱动的联动属性了!
这里是等价的C#代码,我把它写在了Window1的构造函数里:
- public Window1()
- {
- InitializeComponent();
- // 1. 我打算用slider1作为Source
- // 2. 我打算用textBox1作为Target
- Binding binding = new Binding();
- binding.Source = this .slider1;
- binding.Path = new PropertyPath( "Value" );
- this .textBox1.SetBinding(TextBox.TextProperty, binding);
- }
- public Window1()
- {
- InitializeComponent();
- // 1. 我打算用slider1作为Source
- // 2. 我打算用textBox1作为Target
- Binding binding = new Binding();
- binding.Source = this.slider1;
- binding.Path = new PropertyPath("Value");
- this.textBox1.SetBinding(TextBox.TextProperty, binding);
- }
有意思的是,Source端的操作,接管子和插管芯分两步,而Target端却是在SetBinding方法中一步完成。注意啦,TextBox.TextProperty就是一个Dependency Property的庐山真面目!关于Dependency Property的文档业已完成,我将择一黄道吉日挂将出来:p
上面的代码稍有简化的余地,那就是把Path的设定转移到Binding的构造中去:
- public Window1()
- {
- InitializeComponent();
- // 1. 我打算用slider1作为Source
- // 2. 我打算用textBox1作为Target
- Binding binding = new Binding( "Value" );
- binding.Source = this .slider1;
- this .textBox1.SetBinding(TextBox.TextProperty, binding);
- }
- public Window1()
- {
- InitializeComponent();
- // 1. 我打算用slider1作为Source
- // 2. 我打算用textBox1作为Target
- Binding binding = new Binding("Value");
- binding.Source = this.slider1;
- this.textBox1.SetBinding(TextBox.TextProperty, binding);
- }
这样做的好处是——随便你给binding指定一个Source,只要这个Source有“Value”这个属性,binding就会自动提取它的值并传输给Target端。
我们还可以为binding设些“关卡”:
- public Window1()
- {
- InitializeComponent();
- // 1. 我打算用slider1作为Source
- // 2. 我打算用textBox1作为Target
- Binding binding = new Binding( "Value" );
- binding.Source = this .slider1;
- binding.Mode = BindingMode.TwoWay;
- binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
- this .textBox1.SetBinding(TextBox.TextProperty, binding);
- }
- public Window1()
- {
- InitializeComponent();
- // 1. 我打算用slider1作为Source
- // 2. 我打算用textBox1作为Target
- Binding binding = new Binding("Value");
- binding.Source = this.slider1;
- binding.Mode = BindingMode.TwoWay;
- binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
- this.textBox1.SetBinding(TextBox.TextProperty, binding);
- }
还有一个小小的提示:如果Source碰巧是一个UI元素,那么也可将binding.Source = this.slider1;改写成binding.ElementName = "slider1";或者binding.ElementName = this.slider1.Name;
转载于:https://blog.51cto.com/apprentice/1360652