如何建立一个“绑定友好的”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. 空间的配置和释放 std::alloc

    看完了对象的构造行为和内存释放前的对象的析构行为,我们现在来看看内存的配置和释放. 对象构造前的空间分配和析构后的空间释放,定义在头文件<stl_alloc.h>中.其设计思想是: 向sy ...

  2. 日志分析(二) logstash patterns

    grok-patterns内置了很多基础变量的正则表达式的log解析规则,其中包括apache的log解析(同样可以用于nginx的log解析).   基于nginx日志分析配置: 1.配置nginx ...

  3. java_闭包和回调实现一边按键盘一边演讲

    package ming; interface Teachable { void work(); } class Programer { private String name; public Str ...

  4. Helpers\RainCaptcha

    Helpers\RainCaptcha This class can validate CAPTCHA images with RainCaptcha. It can generate an URL ...

  5. A+B Problem(V)

    描述 做了A+B Problem之后,Yougth感觉太简单了,于是他想让你求出两个数反转后相加的值.帮帮他吧 输入 有多组测试数据.每组包括两个数m和n,数据保证int范围,当m和n同时为0是表示输 ...

  6. css笔记02:选择器(标签式和类)

    body { margin:; padding:; background:#000 url('images/backgrounds/star.png') no-repeat fixed; font: ...

  7. 【VMware虚拟化解决方案】设计和配置VMware vCenter 5.5

    在这之前,我们已经对VMware ESXi 5.5进行了整个环境的设计和规划,虽然安装VMware ESXi 5.5在CPU的选型.网络的设计.共享存储的方式.虚拟化资源的需求和安装ESXI的模式等一 ...

  8. 实现TableLayout布局下循环取出TableRow控件中的文字内容到list集合

    布局方式为TableLayout,利于实现表单样式展现. <!-- 详情内容区域 --> <ScrollView android:layout_above="@id/id_ ...

  9. JS中的原型继承和多重继承

    概念:1原型继承是创建新类型对象----子类型,子类型基于父类型,子类型拥有父类型所有的属性和方法(从父类型继承得到),然后修改其中的部分内容或者添加新的内容.继承最好在子类型模型可以被视为父类型对象 ...

  10. sqlserver 公有表达式

    了解通用表达式: 为了让代码简洁:在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解,但是视图是系统级对象,如果数据集仅仅需要在存储过程或是自定义函数中使用一次的话,使用view有些奢侈哈 ...