如何建立一个“绑定友好的”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 ...
随机推荐
- UNIX标准化及实现之POSIX标准扩展头文件
POSIX标准定义的XSI(X/Open System Interface)扩展头文件 头文件 说明 <cpio.h> cpio归档值 <dlfcn.h> 动态链接 <f ...
- VBA Mysql 类
Option Explicit '==================================== 声明属性 =================================Private ...
- C语言中堆和栈的区别
原文:http://blog.csdn.net/tigerjibo/article/details/7423728 C语言中堆和栈的区别 一.前言: C语言程序经过编译连接后形成编译.连接后形成的二进 ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...
- Apache以及PHP的默认编码问题解决(详解)
如果你在网上搜索 “apache配置”,搜到的页面大多都会建议你在httpd.conf中加上这么一句:AddDefaultCharset GB2312.对于新手而且是只用GB2312编码的开发人来说, ...
- VBA-工程-找不到工程或库-解决方案
近来,越来越多的朋友被“找不到工程或库”的错误所烦恼,所以决定新开一帖来聊聊此问题! QUOTE: 一般情况下,出现此错误是因为找不到引用工程,或找不到与工程语言对应的引用的对象库 出现此类错误可以根 ...
- Linux 下memcache安装及使用
memcache是高性能,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度.据说官方所说,其用户包括twitter.digg.flickr等,都是些互联网大腕呀.目前用memca ...
- .net 在不同情况下调用带soapheader的webservice的方式
国庆长假到了,本想出去玩玩,无奈自己屌丝一枚,啥都没有,只能自己宅在家里思考思考人生.不过人生还是过于复杂,一时间也想不出个所以然,只能是整理一下在工作中遇到的一些小问题,首先是关于带soaphead ...
- ArcEngine中打开各种数据源(WorkSpace)的连接http://www.cnblogs.com/feilong3540717/archive/2011/08/07/2129906.html
ArcEngine中打开各种数据源(WorkSpace)的连接 ArcEngine中打开各种数据源(WorkSpace)的连接 (SDE.personal/File.ShapeFile.CAD数据.影 ...
- Log4Net(三)之记录日志到数据库
前面两篇短文向大家介绍了如何使用log4net,以及如何将log4net记录到文本文件中.下面本文将向大家介绍如何将log4net记录到数据库中. 经过前面的介绍,我想大家对使用log4net的过程已 ...