如何建立一个“绑定友好的”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 ...
随机推荐
- java_io_操作封装
package com.wiker; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import j ...
- JSONP(处理跨域问题)
Ajax直接请求普通文件存在跨域无权限访问的问题 凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>.<img>.<iframe& ...
- Step-by-Step XML Free Spring MVC 3 Configuration--reference
The release of Spring 2.5 reduce the burden of XML by introduction annotation based configuration, b ...
- c语言趣味
改编java趣味100题,c语言版 1.C语言版金字塔 #include <stdio.h> int main() { int n,i,j,k; scanf("%d", ...
- Debian 7 安装使用 Virtualbox及增强功能
一.安装virtualbox 可以从源里安装 sudo apt-get install virtualbox 也可以下载最新版安装 https://www.virtualbox.org/wiki/Do ...
- js与asp.net后台交互
1.如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3.如何在C#中访问JavaScript的已有变量? 4.如何在C#中访问JavaScript函数? 问题1 ...
- jquery实现表格行的动态增加和删除
$("#Addmaterial").click(function () {//Addmaterial是增加按钮的ID $("#tab tr").attr(&qu ...
- 最短路径之Dijkstra算法及实例分析
Dijkstra算法迪科斯彻算法 Dijkstra算法描述为:假设用带权邻接矩阵来表示带权有向图.首先引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点Vi的最短路径.它的初始 ...
- linux开机启动配置
vim /etc/rc.d/rc.local 把命令写在这里
- 24小时学通Linux内核--内核探索工具类
寒假闲下来了,可以尽情的做自己喜欢的事情,专心待在实验室里燥起来了,因为大二的时候接触过Linux,只是关于内核方面确实是不好懂,所以十天的时间里还是希望能够补充一下Linux内核相关知识,接下来继续 ...