如何建立一个“绑定友好的”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的更多相关文章

  1. [转]使用Scrapy建立一个网站抓取器

    英文原文:Build a Website Crawler based upon Scrapy 标签: Scrapy Python 209人收藏此文章, 我要收藏renwofei423 推荐于 11个月 ...

  2. jmeter 建立一个扩展LDAP测试计划

    添加用户 第一步你想做的每一个JMeter测试计划是添加一个线程组元素. 线程组告诉JMeter的用户数量你想模拟,用户应该发送的次数 请求,他们应该发送的请求的数量. 继续添加 线程组 首先选择元素 ...

  3. Android在如何建立一个WebServer

    今天老板交待任务最终完成了,感觉收获颇多,所以写一个关于它的记录,首先,看一下.老板的需求 需求: 希望移动端的用户标识(IMEI)和HTML页面的用户标识(Cookie)连接起来,当中HTML页面可 ...

  4. Hyperledger Fabric 建立一个简单网络

    Building you first network 网络结构: 2个Orgnizations(每个Org包含2个peer节点)+1个solo ordering service 打开fabric-sa ...

  5. Rails 建立一个资源

    在blog 应用程序中.你可以通过脚手架(scaffolded)开始建立一个资源. 这将是单一的blog 提交.请输入以下命令 $ rails generate scaffold Post name: ...

  6. Hyberledger-Fabric 1.00 RPC学习(2)尝试建立一个network

    本文参考:http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html 这里我们学习建立第一个Hyperledger Fa ...

  7. VS下如何建立一个新的MFC程序 网络编程 课设 基于C++ MFC 连接数据库 小应用 小项目浅析展示

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/8191036.html 这里不知道会不会有人是真的新手 新新手 不知道怎么 如何建立一个MFC ...

  8. 建立一个能持续处理的C/S网络程序

    程序流程图: 代码演示: 服务器端: #include<WinSock2.h> #include<Windows.h> #include<stdio.h> #inc ...

  9. 建立一个可以不停地接收客户端新的连接,但不能处理复杂的业务的C/S网络程序

    在Windows平台上主要有两个版本的Socket Api函数:WinSock 1.1和WinSock 2.2 , 2.2版本默认兼容1.1版本,1.1 winsock.h wsock32.lib w ...

随机推荐

  1. C++重载(主要介绍使用友元函数重载)

    重载限制 多数C++运算符都可以用下面的方式重载.重载的运算符不必是成员函数,但必须至少有一个操作数是用户自定义的类型.下面详细介绍C++对用户定义的运算符重载的限制. 1 重载后的运算符必须至少有一 ...

  2. Javassist初体验

           最初接触javassist是在研究dubbo源码的时候,那会对其的理解还停留在动态生成字节码的位置,可以做动态代理之类的动态化处理.最近由于项目需要扫描springMVC中control ...

  3. FatMouse' Trade

    /* problem: FatMouse' Trade this is greedy problem. firstly:we should calculate the average J[i]/F[i ...

  4. SCI&EI 英文PAPER投稿经验【转】

    英文投稿的一点经验[转载] From: http://chl033.woku.com/article/2893317.html 1. 首先一定要注意杂志的发表范围, 超出范围的千万别投,要不就是浪费时 ...

  5. 1. Android 系统上一款开源的图表库

    1. MPAndroidChart  MPAndroidChart 是 Android 系统上一款开源的图表库.目前提供线图和饼图,支持选择.缩放和拖放. 一个可以拖动缩放的图表库,包含曲线图.直方图 ...

  6. Android(java)学习笔记100:android开发中修改字体

    首先如果android内部自带的字体不是我们需要的字体,那我们就需要字体文件导入到android开发工程中,下午我们详细讲述: 1.我们首先分析知道,我想要TextView控件中文字的字体是:华文楷体 ...

  7. ASP.NET MVC and jqGrid 学习笔记 3-如何从数据库获得数据

    实际应用中,大部分都是从数据库里获得数据,所以先建立一个数据库,Database first 或者Code first都可以,这里用Code first. 一.Model public class M ...

  8. Eclipse输入任意字母或指定字符出现提示框

    Eclipse默认是输入"."的时候会有提示框提示对应的API. 如果想更方便的输入任意字母或者指定的符号出现提示框设置如下: 打开Eclipse,选中“Window”->& ...

  9. C# 32位md5

    /// <summary> /// 获得32位的MD5加密 /// </summary> /// <param name="str">加密字符串 ...

  10. Sublime Text—设置浏览器快捷键

    在不同浏览器查看代码效果可谓是家常便饭,所以用不同快捷键打开相应浏览器可以大大提高工作效率. 介绍个简单的方法只需二步: 一.安装插件SideBarEnhancements 打开Package Con ...