如何建立一个“绑定友好的”usercontrol--wpf
如何建立一个“绑定友好的”usercontrol--wpf
这几天在打算将以前用winform写的工具程序重构到wpf,顺便学习理解看过的wpf的知识。
因为程序设计到一个Excel文件的读取和操作,比较耗时,所以打算制作一个缓冲动画。该动画应该分为两个部分,一个部分是“一排一次排列的方块组成的渐变动画”,一部分是一个Label类的控件,用来显示后台操作Excel时候的进度。
先放上渐变动画的Xaml,在usercontrol里面加上以下代码就行了。这个不是今天记录的重点。
</Canvas.Triggers>
现在重点来说说label类控件显示进度描述的,因为打算在自定义控件中利用binding来进行实时的通知,所以这个usercontrol必须是一个绑定友好的控件。
网上也查找了不少,也问了问同事,著名的“老赵”(不敢妄加评论大神,勿怪)和同事都是为usercontrol配一个viewmodle来实现binding的友好,但是这种不是我想要的,总觉得给一个控件配一个viewmodle不太舒服。就想实现普通类似:
如上代码的binding。
继续百度+看书,确认可以使用依赖属性来暴露出usercontrol的一个属性,利用这个属性来实现bind。
这里我重新制作了一个usercontrol,核心是两个TextBlock,对第二个TextBlock中的text部分设置进行一个属性暴露的操作。
代码如下xmal:
这个usercontrol对应的后台代码:
///
/// DoubleTextBox.xaml 的交互逻辑
///
public partial class DoubleTextBox : UserControl
{
public DoubleTextBox()
{
InitializeComponent();
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("TempName", typeof(string),
typeof (DoubleTextBox),new PropertyMetadata("TextBlock",new PropertyChangedCallback(OnTextChanged)));
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DoubleTextBox dtb = (DoubleTextBox) d;
dtb.txtBox2.Text = (string) e.NewValue;
}
public string TempName
{
get { return (string) GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
}
这里使用DependencyProperty定义一个依赖属性ValueProperty,利用register操作进行注册,
说一下各个参数的含义:
1:暴露出来的属性名称,这里为“TempName”,可以如下使用
<localControl:DoubleTextBox Height="200" TempName="{Binding Name}"></localControl:DoubleTextBox>
2:暴露出的属性的类型,这里是字符串string
3:属性所有者的名字,看前面的定义,“Temp”是“DoubleTextBox”的一个公开属性,所以名字就是DoubleTextBox
4:用来处理属性改变时候的操作,回调函数参数1:就是依赖属性的默认值,随便给一个string类型都可以 2、具体处理方法
如上,一个bind友好的控件就制作完了,可以在此基础上继续改造升级。
放一个简单的使用demo(不包含渐变动画):
建立一个testWindow,在里面使用控件(命名中的拼写错误请忽略)
<localControl:DoubleTextBox Height="200" TempName="{Binding Name}"></localControl:DoubleTextBox>
这其中,xmlns:localControl="clr-namespace:MetroTest.LoaclControl"是我自定义控件所放置的文件夹的路径。
界面组成:1、定义好的uercontrol 2、一个button 3、一个Textblock
分别用处:1、不用说了 2、导向一个vm中的command用来更新bind的内容 3、检查是不是bind更新成功的
写一个简单的VieModle(忽略command的命名,copy的其他工程的)
class TextViewModle:ViewModleBase
{
private string _name;
public string Name
{
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged("Name");
}
}
get { return _name; }
}
private int count = 1;
//定义一个命令
public ICommand OpenFileCommand { get { return new RelayCaommand(OpenFileExecute, CanOpenFileExecute); } }
private bool CanOpenFileExecute()
{
return true;
}
private void OpenFileExecute()
{
Name = count.ToString();
count++;
}
}
记得给TestWindow的datacontent进行绑定。(命名中的拼写错误请忽略)
///
/// Test.xaml 的交互逻辑
///
public partial class Test : Window
{
public Test()
{
InitializeComponent();
this.DataContext = new TextViewModle();
}
}
到此,一个简单的例子就完成了,水平浅陋,希望对大家有帮助。。
顺便推销个人博客:http://www.dingshuo89.top
浙公网安备 33010602011771号