如何建立一个“绑定友好的”usercontrol--wpf
如何建立一个“绑定友好的”usercontrol--wpf
这几天在打算将以前用winform写的工具程序重构到wpf,顺便学习理解看过的wpf的知识。
因为程序设计到一个Excel文件的读取和操作,比较耗时,所以打算制作一个缓冲动画。该动画应该分为两个部分,一个部分是“一排一次排列的方块组成的渐变动画”,一部分是一个Label类的控件,用来显示后台操作Excel时候的进度。
先放上渐变动画的Xaml,在usercontrol里面加上以下代码就行了。这个不是今天记录的重点。
<Canvas Margin="0,0,0,50">
<Rectangle x:Name="r1" Fill="Black" Opacity="1" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="20" Canvas.Top="16"/>
<Rectangle x:Name="r2" Fill="Black" Opacity="0.9" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="70" Canvas.Top="16"/>
<Rectangle x:Name="r3" Fill="Black" Opacity="0.8" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="120" Canvas.Top="16"/>
<Rectangle x:Name="r4" Fill="Black" Opacity="0.7" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="170" Canvas.Top="16"/>
<Rectangle x:Name="r5" Fill="Black" Opacity="0.6" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="220" Canvas.Top="16"/>
<Rectangle x:Name="r6" Fill="Black" Opacity="0.5" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="270" Canvas.Top="16"/>
<Rectangle x:Name="r7" Fill="Black" Opacity="0.4" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="320" Canvas.Top="16"/>
<Rectangle x:Name="r8" Fill="Black" Opacity="0.3" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="370" Canvas.Top="16"/>
<Rectangle x:Name="r9" Fill="Black" Opacity="0.2" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="420" Canvas.Top="16"/>
<Rectangle x:Name="r10" Fill="Black" Opacity="0.1" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="30" Canvas.Left="470" Canvas.Top="16"/>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard >
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="r1" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0" To="0"/>
<DoubleAnimation Storyboard.TargetName="r2" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.08" To="0"/>
<DoubleAnimation Storyboard.TargetName="r3" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.16" To="0"/>
<DoubleAnimation Storyboard.TargetName="r4" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.24" To="0"/>
<DoubleAnimation Storyboard.TargetName="r5" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.32" To="0"/>
<DoubleAnimation Storyboard.TargetName="r6" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.40" To="0"/>
<DoubleAnimation Storyboard.TargetName="r7" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.48" To="0"/>
<DoubleAnimation Storyboard.TargetName="r8" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.56" To="0"/>
<DoubleAnimation Storyboard.TargetName="r9" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.64" To="0"/>
<DoubleAnimation Storyboard.TargetName="r10" Storyboard.TargetProperty="Opacity" AutoReverse="True" Duration="0:0:0.08" BeginTime="0:0:0.72" To="0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
现在重点来说说label类控件显示进度描述的,因为打算在自定义控件中利用binding来进行实时的通知,所以这个usercontrol必须是一个绑定友好的控件。
网上也查找了不少,也问了问同事,著名的“老赵”(不敢妄加评论大神,勿怪)和同事都是为usercontrol配一个viewmodle来实现binding的友好,但是这种不是我想要的,总觉得给一个控件配一个viewmodle不太舒服。就想实现普通类似:
<TextBlock Text="{Binding Name}" Height="30"/>
如上代码的binding。
继续百度+看书,确认可以使用依赖属性来暴露出usercontrol的一个属性,利用这个属性来实现bind。
这里我重新制作了一个usercontrol,核心是两个TextBlock,对第二个TextBlock中的text部分设置进行一个属性暴露的操作。
代码如下xmal:
<UserControl x:Class="MetroTest.LoaclControl.DoubleTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="300">
<Grid>
<StackPanel>
<Label Content="A"></Label>
<TextBox x:Name="txtBox1" Text="试一试" Height="30" Margin="5"/>
<Label Content="B"></Label>
<TextBox x:Name="txtBox2" Height="30" Margin="5"/>
</StackPanel>
</Grid>
</UserControl>
这个usercontrol对应的后台代码:
/// <summary>
/// DoubleTextBox.xaml 的交互逻辑
/// </summary>
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,在里面使用控件(命名中的拼写错误请忽略)
<Window x:Class="MetroTest.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:localControl="clr-namespace:MetroTest.LoaclControl"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Title="Test" Height="300" Width="594">
<StackPanel>
<localControl:DoubleTextBox Height="200" TempName="{Binding Name}"></localControl:DoubleTextBox>
<Button Command="{Binding OpenFileCommand}">Submit</Button>
<TextBlock Text="{Binding Name}" Height="30"/>
</StackPanel>
</Window>
这其中,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进行绑定。(命名中的拼写错误请忽略)
/// <summary>
/// Test.xaml 的交互逻辑
/// </summary>
public partial class Test : Window
{
public Test()
{
InitializeComponent();
this.DataContext = new TextViewModle();
}
}
到此,一个简单的例子就完成了,水平浅陋,希望对大家有帮助。。
顺便推销个人博客:http://www.dingshuo89.top
如何建立一个“绑定友好的”usercontrol--wpf的更多相关文章
- [转]使用Scrapy建立一个网站抓取器
英文原文:Build a Website Crawler based upon Scrapy 标签: Scrapy Python 209人收藏此文章, 我要收藏renwofei423 推荐于 11个月 ...
- jmeter 建立一个扩展LDAP测试计划
添加用户 第一步你想做的每一个JMeter测试计划是添加一个线程组元素. 线程组告诉JMeter的用户数量你想模拟,用户应该发送的次数 请求,他们应该发送的请求的数量. 继续添加 线程组 首先选择元素 ...
- Android在如何建立一个WebServer
今天老板交待任务最终完成了,感觉收获颇多,所以写一个关于它的记录,首先,看一下.老板的需求 需求: 希望移动端的用户标识(IMEI)和HTML页面的用户标识(Cookie)连接起来,当中HTML页面可 ...
- Hyperledger Fabric 建立一个简单网络
Building you first network 网络结构: 2个Orgnizations(每个Org包含2个peer节点)+1个solo ordering service 打开fabric-sa ...
- Rails 建立一个资源
在blog 应用程序中.你可以通过脚手架(scaffolded)开始建立一个资源. 这将是单一的blog 提交.请输入以下命令 $ rails generate scaffold Post name: ...
- Hyberledger-Fabric 1.00 RPC学习(2)尝试建立一个network
本文参考:http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html 这里我们学习建立第一个Hyperledger Fa ...
- VS下如何建立一个新的MFC程序 网络编程 课设 基于C++ MFC 连接数据库 小应用 小项目浅析展示
原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/8191036.html 这里不知道会不会有人是真的新手 新新手 不知道怎么 如何建立一个MFC ...
- 建立一个能持续处理的C/S网络程序
程序流程图: 代码演示: 服务器端: #include<WinSock2.h> #include<Windows.h> #include<stdio.h> #inc ...
- 建立一个可以不停地接收客户端新的连接,但不能处理复杂的业务的C/S网络程序
在Windows平台上主要有两个版本的Socket Api函数:WinSock 1.1和WinSock 2.2 , 2.2版本默认兼容1.1版本,1.1 winsock.h wsock32.lib w ...
随机推荐
- Playing with ptrace, Part I
X86_64 的 Redhat / Centos / Scientific 下面,若要编译.运行32位程序,需要安装以下包: yum install libgcc.i686 yum install g ...
- 高级I/O之readn和writen函数
管道.FIFO以及某些设备,特别是终端.网络和STREAMS设备有下列两种性质: (1)一次read操作所返回的数据可能少于所要求的数据,即使还没有达到文件尾端也可能是这样.这不是一个错误,应当继续读 ...
- DebugView图文教程
Debug信息捕获软件. 可以很方便的捕获系统实时输出的Debug信息,并保存为日志文件.可以远程捕获服务器上的Debug信息. 比较方便开发人员在系统发布前监控一些系统流程和异常,甚至在系统不大的情 ...
- Qt 显示透明flash和编写QtWebkit插件
Qt 有两种方法可以显示flash. 1. 通过QAxWidget 调用com形式显示flash, 需要本机安装IE flash插件 2. 直接通过qwebview显示flash, 需要下载webki ...
- Linux 学习笔记 查看文件内容诸多命令
查看文件内容 1.查看文件统计信息 stat 提供文件系统上某个文件的所有状态信息 2.查看文件类型 file 用来查看文件类型 (该命令将文件分成3类:文本类型:可执行文件:数据文件) 如果你有从未 ...
- [PHP] Eclipse开发PHP环境配置
首先准备好软件: 1. Apache,到这里找个最新版本 2. PHP,到这里下载 3. Eclipse IDE for Java EE Developers,到这里下载 4. DLTK Core F ...
- hdu 1170 Balloon Comes!
Balloon Comes! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- Jquery 全选、反选问题解析
最近工作中,需要使用Jquery实现复选框的全选和反选,本人虽然不是专职撸前端的,但这个小问题感觉也没什么难度,下面直接上代码: <div id="list"> < ...
- Linux 命令 - ftp: 网络文件传输工具
命令格式 ftp [-pinegvd] [host] 命令参数 -A 传输文件模式为主动模式. -p 传输文件模式为被动模式. -i 关闭交互模式. -n 关闭自动登录功能. -e 不记录历史命令. ...
- NGUI的原理机制:深入剖析UIPanel,UIWidget,UIDrawCall底层原理
这是我去搜狐畅游面试时,面试官问的一个问题.问NGUI的机制原理是什么?就是这个插件是根据什么写出来的.当时没答上来,下面是我从转载过来的,可以研究研究. 之前项目中用的NGUI的版本是3.0.7 f ...