wpf中UserControl的几种绑定方式
2016-05-27 16:05
405 查看
我们经常会抽取一些可重用的控件,某个属性是否需要重用,直接决定了这个属性的绑定方式。
使用的时候直接
抽出所有可变的属性,定义在控件内部
绑定控件内定义的这些属性
外部使用时,再将这些属性与vm绑定
具体如下:
相应的cs代码为:
使用的时候为:
特别注意
缺点是,在级联的自定义控件里,简直是个噩梦。设想有3个UserControl:C>B>A (C包含B、B包含A)。只有C有对应的vm,这种情况下B要包含A的所有属性。实际情况是,B要包含所有子控件的所有属性,这无疑是让人郁闷的!
好在多数情况下我们并不需要级联嵌套自定义控件,而且我们也可以放弃一些复用性,以获得默认绑定vm的便利。
使用的时候为:
这种情况下,即使是级联,
1、完全不可重用的控件
有一些与业务强相关的控件,它们的属性完全来自ViewModel,越是相对复杂的控件,越容易这样。比如:// ChooseUc.xaml <UserControl> <StackPanel Orientation="Horizontal"> <Label Content="选择一个水果: "/> <ComboBox ItemsSource="{Binding Fruits}"/> </StackPanel> </UserControl>
使用的时候直接
<my:ChooseUc />即可直接绑定到ViewModel里的
List<Fruit> Fruits,不用做额外的工作。好处是特别方便,代价是与vm完全耦合。
2、完全可重用的控件
类似的控件多了,就能抽出一些完全可重用的控件,这些控件与业务无关。为了实现这种重用性,要做到:抽出所有可变的属性,定义在控件内部
绑定控件内定义的这些属性
外部使用时,再将这些属性与vm绑定
具体如下:
// ChooseUc.xaml <UserControl> <StackPanel x:Name="root" Orientation="Horizontal"> <Label Content="{Binding Header}"/> <ComboBox ItemsSource="{Binding Items}"/> </StackPanel> </UserControl>
相应的cs代码为:
// ChooseUc.xaml.cs public ChooseUc() { InitializeComponent(); root.DataContext = this; // 这句很关键! } public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(IEnumerable), typeof(ChooseUc)); public IEnumerable Items { get { return (IEnumerable)GetValue(ItemsProperty); } set { SetValue(ItemsProperty, value); } } //HeaderProperty类似,此处省略
使用的时候为:
<my:ChooseUc Header="{Binding FruitHeader}" Items="{Binding Fruits}" />
特别注意
root.DataContext = this;,这一句把内部的控件与外界隔离了,内部事实上已经看不到ViewModel了,只能看到内部定义的属性(Header、Items之类的)。麻烦一些,但好处是可以适用于1个标签+1个下拉框的任何场景,复用性高。
缺点是,在级联的自定义控件里,简直是个噩梦。设想有3个UserControl:C>B>A (C包含B、B包含A)。只有C有对应的vm,这种情况下B要包含A的所有属性。实际情况是,B要包含所有子控件的所有属性,这无疑是让人郁闷的!
好在多数情况下我们并不需要级联嵌套自定义控件,而且我们也可以放弃一些复用性,以获得默认绑定vm的便利。
3、部分可重用的控件
还有一类情况就是控件部分可重用,考虑这样一个场景:用户可以选择2个水果,这时Fruits可以直接绑到vm里,但
SelectedFruit需要分别绑定:
// ChooseUc.xaml <UserControl x:Name="uc"> <StackPanel Orientation="Horizontal"> <Label Content="选择一个水果: "/> <ComboBox ItemsSource="{Binding Fruits}" SelectedItem="{Binding SelectedFruit, ElementName=uc}"/> </StackPanel> </UserControl> // 类似的,ChooseUc.xaml.cs里定义SelectedFruit依赖属性
使用的时候为:
<StackPanel> <my:ChooseUc SelectedFruit="{Binding Fruit1}" /> <my:ChooseUc SelectedFruit="{Binding Fruit2}" /> </StackPanel>
这种情况下,即使是级联,
Fruits也不需要重复定义,又获得了
SelectedFruit的灵活性。这里的关键是:只把需要复用的属性,绑定到控件内部,其他属性继承vm就好。
4、小结
实际开发的过程中,大部分的情况是1+3,即完全不重用+部分重用的控件。即使遇到完全重用的控件,也不大会形成级联。相关文章推荐
- 找水王2
- random 函数
- 期末设计(十三周)
- 期末设计(十二周)
- Zookeeper实战之单机集群模式
- 跟我一起学Microsoft SQL Server 2012 Internals(3.3)
- 14.6 守护线程
- DELPHI中EXCEL组件的使用方法
- sparkStreaming的工作原理
- JavaScript 教程
- 354 div2 C:两指针滑动区间
- Partition List
- gson框架的使用
- 柴俊理金:5月27号黄金,宁贵沥青操作建议
- MSSQL事务与视图
- 关于在extjs中使用column布局,不能显示textfield的标签(fieldLabel)解决方法
- 初学linux命令-mkdir、rm、rmdir、mv
- jquery动态添加数据,数据分页
- 获取汉字拼音首字母
- 14.5 wait和notify方法 停止线程