博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Silverlight入门系列]使用MVVM模式(6):使用Behavior
阅读量:6197 次
发布时间:2019-06-21

本文共 6266 字,大约阅读时间需要 20 分钟。

Behavior把一些常用的行为封装成可重复使用的组件(Component)在理想状况下,Designer(设计师)domain expert(特定领域的专家,例如财会人员、HR人员、或MIS)甚至可以完全不需要具备程序设计的观念,只需要了解基础的事件(Event)观念,就可以顺利的开发出一套系统,若需要实现特定的功能时,可商请developere为他们开发所需要的Behaviordesigner只需要取得这些Behavior并使用即可。例如,界面设计人员可以使用Expression Blend把一个Behavior拖到一个界面元素上,比如右键点击以后启动一段动画这个行为,这个界面元素就会自动执行,岂不是很清爽!(当然,执行函数还是要编程人员编写),来个例子:

界面xaml:

ExpandedBlockStart.gif
View Code
1
<
UserControl
2
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
4
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
5
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
6
xmlns:wm
="clr-namespace:AsycValidation"
7
xmlns:i
="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei
="http://schemas.microsoft.com/expression/2010/interactions"
x:Class
="AsycValidation.MainPage"
8
mc:Ignorable
="d"
9
x:Name
="MyUserControl"
10
d:DesignHeight
="300"
d:DesignWidth
="400"
>
11
12
<
Grid
x:Name
="Layout"
>
13
<
TextBlock
Height
="32"
HorizontalAlignment
="Left"
Margin
="41,53,0,0"
x:Name
="textBlock1"
Text
="Company:"
VerticalAlignment
="Top"
Width
="66"
/>
14
<
TextBox
Height
="31"
HorizontalAlignment
="Left"
Margin
="120,45,0,0"
x:Name
="textBox1"
Text
="
{Binding CompanyName, Mode=TwoWay, NotifyOnValidationError=True}
"
VerticalAlignment
="Top"
Width
="119"
/>
15
<
TextBox
Height
="30"
HorizontalAlignment
="Left"
Margin
="120,104,0,0"
x:Name
="textBox2"
Text
="
{Binding CompanyID, Mode=TwoWay, NotifyOnValidationError=True}
"
VerticalAlignment
="Top"
Width
="119"
/>
16
<
Button
Content
="Button"
Height
="36"
HorizontalAlignment
="Left"
Margin
="120,156,0,0"
x:Name
="button1"
VerticalAlignment
="Top"
Width
="81"
>
17
<
i:Interaction.Triggers
>
18
<
i:EventTrigger
EventName
="Click"
>
19
<
ei:CallMethodAction
MethodName
="button1_Click"
TargetObject
="
{Binding ElementName=MyUserControl}
"
/>
20
</
i:EventTrigger
>
21
<
i:EventTrigger
>
22
<
ei:CallMethodAction
MethodName
="button1_loaded"
TargetObject
="
{Binding ElementName=MyUserControl}
"
/>
23
</
i:EventTrigger
>
24
</
i:Interaction.Triggers
>
25
</
Button
>
26
</
Grid
>
27
 
</
UserControl
>

界面xaml.cs:

ExpandedBlockStart.gif
View Code
1
using
System;
2
 
using
System.Collections.Generic;
3
 
using
System.Linq;
4
 
using
System.Net;
5
 
using
System.Windows;
6
 
using
System.Windows.Controls;
7
using
System.Windows.Documents;
8
using
System.Windows.Input;
9
using
System.Windows.Media;
10
using
System.Windows.Media.Animation;
11
using
System.Windows.Shapes;
12
13
namespace
AsycValidation
14
{
15
public
partial
class
MainPage : UserControl
16
{
17
public
MainPage()
18
{
19
InitializeComponent();
20
21
CompanyModel m1
=
new
CompanyModel() { CompanyID
=
1
, CompanyName
=
"
abc
"
};
22
23
companyViewModel
=
new
CompanyViewModel(m1);
24
this
.DataContext
=
companyViewModel;
25
26
}
27
28
public
void
button1_Click()
29
{
30
MessageBox.Show(
"
ok
"
);
31
}
32
33
public
void
button1_loaded()
34
{
35
MessageBox.Show(
"
loaded
"
);
36
37
}
38
39
public
CompanyViewModel companyViewModel {
get
;
set
; }
40
41
}
42
}

注意给这个button定义了两个CallMethodAction的behavior:一个是点击事件,一个是加载Loaded事件。

1
<
Button
Content
="Button"
Height
="36"
HorizontalAlignment
="Left"
Margin
="120,156,0,0"
x:Name
="button1"
VerticalAlignment
="Top"
Width
="81"
>
2
<
i:Interaction.Triggers
>
3
<
i:EventTrigger
EventName
="Click"
>
4
<
ei:CallMethodAction
MethodName
="button1_Click"
TargetObject
="
{Binding ElementName=MyUserControl}
"
/>
5
</
i:EventTrigger
>
6
<
i:EventTrigger
>
7
<
ei:CallMethodAction
MethodName
="button1_loaded"
TargetObject
="
{Binding ElementName=MyUserControl}
"
/>
8
</
i:EventTrigger
>
9
</
i:Interaction.Triggers
>
10
</
Button
>

实现步骤:在VS2010中右键点击xaml文件“在Expression Blend中打开...”,然后左边拖一个Behavior到控件上来,配置属性,保存即可。要注意的是TargetObject属性配置。

Behavior or Command?

commandsandbehavior

MVVM设计模式为了实现UI元素也UI界面逻辑分离项目组决定使用MVVM设计模式。把界面逻辑写在ViewModel层,View层由美工设计,通过绑定VM层的数据,实现分离。可是问题出来了,UI元素如何触发VM层的事件呢? 最开始很多人建议使用command命令,因为silverlight/wpf的很多控件都提供了Command属性。感觉还挺好使,只需要绑定VM层的ICommand属性就可以了。可是后来问题越来越复杂,主要出来以下几方面的问题:

  (1) 只有ButtonBase提供了Command属性。其他没有继承这个基类的元素不提供此接口。需要自己扩展。

  (2) UI元素事件一般会有很多,比如左击、右击、拖拉、load、unload等。

  (3) UI元素可能在初始化时就会需要一些操作,比如Load事件。

 

开始我们使用Prism提供的和类来处理,可是对于左、右击这种情况很棘手,重写ICommand,那么多UI元素想累死啊,终于在微软Expression blend中找到答案。使用behavior,一切搞定。

 

Behavior提供、ChangePropertyAction、DataStateBehavior等十三个行为,足够你处理一般事件调用情况了。比如:提供EventName、MethodName两个属性,EventName:你可以选择任意元素事件,MethodName:可以让你直接绑定方法,基本上可以解决所有问题。使用也很简单,只需要在Blend中把相关行为Behavior拖放到控件上,然后设置相关属性,一切OK!

有哪些Behavior可用?

首先在Expression Blend控件库左边的behavior部分已经有好多实现的行为,可直接拖过来用,当然网上资源也很多(如),还能自己扩展。

behavior

自定义Behavior

举个例子,Silverlight文本框的一个老问题就是它只在失去焦点的时候才更新绑定源,失去焦点才做Validation,我们来编写一个behavior可以简单的解决这个问题:textbox文字改变就立即validation并更新绑定数据源。下载本

代码:

ExpandedBlockStart.gif
TextBoxUpdateBehavior : Behavior
1
using
System;
2
using
System.Net;
3
using
System.Windows;
4
using
System.Windows.Controls;
5
using
System.Windows.Documents;
6
using
System.Windows.Ink;
7
using
System.Windows.Input;
8
using
System.Windows.Media;
9
using
System.Windows.Media.Animation;
10
using
System.Windows.Shapes;
11
using
System.Windows.Interactivity;
12
13
namespace
AsycValidation
14
{
15
public
class
TextBoxUpdateBehavior : Behavior
<
TextBox
>
16
{
17
public
TextBoxUpdateBehavior()
18
{
19
}
20
protected
override
void
OnAttached()
21
{
22
base
.OnAttached();
23
AssociatedObject.TextChanged
+=
AssociatedObjectOnTextChanged;
24
}
25
private
void
AssociatedObjectOnTextChanged(
object
sender, TextChangedEventArgs args)
26
{
27
var bindingExpr
=
AssociatedObject.GetBindingExpression(TextBox.TextProperty);
28
bindingExpr.UpdateSource();
29
30
}
31
protected
override
void
OnDetaching()
32
{
33
base
.OnDetaching();
34
AssociatedObject.TextChanged
-=
AssociatedObjectOnTextChanged;
35
}
36
}
37
}

xaml

ExpandedBlockStart.gif
Xaml code
<
UserControl
xmlns:wm
="clr-namespace:AsycValidation"
<TextBox Height
="30"
HorizontalAlignment
="Left"
Margin
="120,104,0,0"
x:Name
="textBox2"
Text
="
{Binding CompanyID, Mode=TwoWay, NotifyOnValidationError=True}
"
VerticalAlignment
="Top"
Width
="119"
>
<
i:Interaction.Behaviors
>
<
wm:TextBoxUpdateBehavior
/>
</
i:Interaction.Behaviors
>
</
TextBox
>
</
UserControl
>

(运行后如何看效果:在第二个textbox输入1,输入2,输入1,看看validation)下载本

(本示例同时演示了Behavior, CustomBehavior, Validation, INotifyPropertyChanged, INotifyDataErrorInfo, MVVM, WCF Ria Service, 异步validation...)

转载地址:http://mmjca.baihongyu.com/

你可能感兴趣的文章
使用AspNetPager与GridView完成分页
查看>>
Spring4.1新特性——静态资源处理增强
查看>>
Java Date Time 教程-java.util.Calendar和GregorianCalendar
查看>>
深入浅出jcr之十 redolog 和 recovery.docx
查看>>
LeetCode 22 Generate Parentheses(生成括号)
查看>>
hdu 3306 Another kind of Fibonacci
查看>>
【SICP练习】116 练习3.42
查看>>
【sql查询与优化】3.操作多个表
查看>>
connecting docker containers on multiple hosts with open vswitch GRE
查看>>
linux网络实现分析(1)——数据包的接收(从网卡到协议栈)
查看>>
自定义 Lint 规则简介
查看>>
从volatile解读ConcurrentHashMap(jdk1.6.0)无锁读
查看>>
学习嵌入式的心得
查看>>
开发一个vue插件并且发布到npm(二)
查看>>
使用koa2+wechaty打造个人微信小秘书
查看>>
自用日志中ThreadLocal的使用
查看>>
前端日刊君来也
查看>>
知识点归档,博客记录
查看>>
docker
查看>>
一文秒懂厂商推送
查看>>