wpf中用户控件的属性重用
我们经常会抽取一些可重用的控件,某个属性是否需要重用,直接决定了这个属性的绑定方式。
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、小结
wpf中用户控件的属性重用的更多相关文章
- WPF中用户控件对比自定义控件(UserControl VS CustomControl)
接着这篇文章(http://www.cnblogs.com/shiyue/archive/2013/02/02/2889907.html)写: 用户控件(组合) 用于在一个项目中使用多次 自定义控件( ...
- WPF中常用控件的属性
Source = new BitmapImage( new Uri( WangCaiConfig.GetCurrentDirectory() + imgStr, UriKind.RelativeOrA ...
- WPF中Image控件的Source属性
原文:WPF中Image控件的Source属性 imgBook 是一个Image控件,在后台代码中我想给它指定Source的属性.我先如下方式进行: Uri uri = new Uri(strImag ...
- WPF中PasswordBox控件的Password属性的数据绑定
原文:WPF中PasswordBox控件的Password属性的数据绑定 英文原文:http://www.wpftutorial.net/PasswordBox.html 中文原文:http://bl ...
- 浅尝辄止WPF自定义用户控件(实现颜色调制器)
主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...
- 示例:WPF中Slider控件封装的缓冲播放进度条控件
原文:示例:WPF中Slider控件封装的缓冲播放进度条控件 一.目的:模仿播放器播放进度条,支持缓冲任务功能 二.进度: 实现类似播放器中带缓存的播放样式(播放区域.缓冲区域.全部区域等样式) 实现 ...
- Android中常用控件及属性
在之前的博客为大家带来了很多关于Android和jsp的介绍,本篇将为大家带来,关于Andriod中常用控件及属性的使用方法,目的方便大家遗忘时,及时复习参考.好了废话不多讲,现在开始我们本篇内容的介 ...
- 对用户控件(ascx)属性(property)赋值
对用户控件(ascx)属性(property)赋值 Insus.NET写此博文,是对用户控件(ASCX)的属性赋值经验与技巧分享.是这样子的,在做新闻站点时,一般都会有分很多类别. 在站点首页会显示最 ...
- WPF中TreeView控件SelectedItemChanged方法的MVVM绑定
问题描述:左侧treeview控件中点击不同类别的节点时,右侧的页面会显示不同的权限.比如对于My Publications,拥有Modify和Delete两种权限,对于My Subscription ...
随机推荐
- TypeScript 面向对象基础知识
孙广东 2016.4.5 JavaScript如今到处都是.web.server(通过NodeJS).移动应用(通过各种框架).全部这些,TypeScript都能够使用,而且能够为JavaScrip ...
- XMPP协议实现即时通讯底层书写 (二)-- IOS XMPPFramework Demo+分析
我希望,This is a new day! 在看代码之前,我认为你还是应该先整理一下心情,来听我说几句: 首先,我希望你是在早上边看这篇blog,然后一边開始动手操作,假设你仅仅是看blog而不去自 ...
- 【微信公众号】微信关于网页授权access_token和普通access_token的区别及两种不同方式授权
微信官网网址:https://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html#.E9.99.84.EF.BC.9A.E6. ...
- Django的CBV与FBV
FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV CBV(class base v ...
- 【LeetCode】73. Set Matrix Zeroes (2 solutions)
Set Matrix Zeroes Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do i ...
- Python3.2官方文档翻译--输出格式化
第八章 标准库二 第二部分涵盖了很多更能满足专业开发者需求的高级模块.这些模块在小脚本中非常少出现. 8.1 输出格式化 Reprlib模块为大型的或深度嵌套的容器缩写显示提供了repr()函数的一个 ...
- 用Visual studio2012在Windows8上开发内核驱动监视进程创建
在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...
- informix-時間格式的各種用法
以下是我在網路上所收集到的關於informix 時間的sql函數用法,有在使用informix資料庫的人,可以參考看看囉! today,返回現在系統日期 current 返回現在日期含時間,相當於sq ...
- hdu 2066 一个人的旅行(dijkstra)
一个人的旅行 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- Linux 硬链接和软链接
硬链接:ln 源文件 新建名 指向同一个文件,并独立存在.当源文件删除不会影响硬链接文件的读取.不能跨文件系统和目录建连接. 例:新建一个文件吧!名字test 硬链接为t1. 查看文件,发现2个文件最 ...