《深入浅出WPF》笔记绑定篇二Word文档格式.docx
《《深入浅出WPF》笔记绑定篇二Word文档格式.docx》由会员分享,可在线阅读,更多相关《《深入浅出WPF》笔记绑定篇二Word文档格式.docx(19页珍藏版)》请在冰点文库上搜索。
if(double.TryParse(value.ToString(),outd))
if(d>
=0&
&
d<
=80)
returnnewValidationResult(true,null);
}
returnnewValidationResult(false,"
输入数字不合理!
!
"
);
B、XAML代码
ViewCode
<
Windowx:
Class="
BindingOfValid.MainWindow"
xmlns="
xmlns:
x="
Title="
MainWindow"
Height="
200"
Width="
300"
>
<
StackPanel>
TextBoxx:
Name="
textbox1"
Margin="
5"
/TextBox>
Sliderx:
slider1"
Minimum="
-10"
Maximum="
110"
/Slider>
/StackPanel>
/Window>
C、cs代码
CS
usingSystem.Windows;
usingSystem.Windows.Data;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Imaging;
usingSystem.Windows.Navigation;
usingSystem.Windows.Shapes;
usingCommonLib;
namespaceBindingOfValid
///<
summary>
///MainWindow.xaml的交互逻辑
/summary>
publicpartialclassMainWindow:
Window
publicMainWindow()
InitializeComponent();
//新建绑定实例,指定源和路径
Bindingbinding=newBinding("
Value"
){Source=this.slider1};
//设置更新绑定源的方式
binding.UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged;
//创建验证条件
RangeValidationRulervr=newRangeValidationRule();
//默认数据源的数据都是正确的,如果加上下面的验证目标更新,则也会验证源的数据是否合法
rvr.ValidatesOnTargetUpdated=true;
//向ValidationRules添加验证条件
binding.ValidationRules.Add(rvr);
//设置通知错误的提示,我们可以把它想象为报警器,它会沿着目标,传到安装处理报警的地方
binding.NotifyOnValidationError=true;
binding.NotifyOnTargetUpdated=true;
//添加对源和目标的更新的监视,设置ToolTip为空
this.TargetUpdated+=newEventHandler<
DataTransferEventArgs>
(MainWindow_TargetUpdated);
this.SourceUpdated+=newEventHandler<
(MainWindow_SourceUpdated);
this.textbox1.SetBinding(TextBox.TextProperty,binding);
//接到报警后,会处理报警(通过路由事件)
this.textbox1.AddHandler(Validation.ErrorEvent,newRoutedEventHandler(this.ValidError));
voidMainWindow_SourceUpdated(objectsender,DataTransferEventArgse)
(senderasMainWindow).textbox1.ToolTip="
;
voidMainWindow_TargetUpdated(objectsender,DataTransferEventArgse)
voidValidError(objectsender,RoutedEventArgse)
if(Validation.GetErrors(this.textbox1).Count>
0)
this.textbox1.ToolTip=Validation.GetErrors(this.textbox1)[0].ErrorContent.ToString();
e.Handled=true;
}
效果图如图1:
图1
本段代码重在理解Binding的数据校验,还有很多细节要进行优化。
再总结一下实现过程:
定义一个验证规则和Binding,把验证规则添加到绑定的验证规则集里面,开启Binding的报警器(NotifyOnValidationError),为指定的UI控件添加路由事件来做出相应的反应。
1.2 Binding的数据转化
在XAML的语法的记录中有出现过转化(TypeConverter),主要是实现XAML标签的Attribute与对象的Property进行映射。
今天要记录的是绑定的数据的转化,在这里可以把Binding比作一笔交易,买家想要某种东西,但是卖家给的却不是成型的产品,所以需要去加工才能成为买家最终想要的产品。
反过来说,买家有的时间不给卖家钱,而是给的黄金或其他有价值的东西,那么如果卖家用钱的话,他要去转化成现金。
同样在使用Binding时,这样的例子也是屡见不鲜了,最明显的我们要把字符串类型的性别转化成布尔型的性别然后绑定到指定的CheckBox上面或者是其他控件上面。
下面举个例子来说明一下,把飞机型号转化成图片路径显示出来,并且可以安排飞机的位置,("
OnAir"
表示在空中,"
OnLand"
表示在陆上,"
Unknow"
表示位置保密),可能我画的飞机不像,但重在说明问题。
A、先定义一个飞机类:
Plane.cs
namespaceChapter_04
publicclassPlane
publicstringCategory{get;
set;
publicstringArea{get;
publicstringState{get;
B、写两个转化类PlaneConVerter和StateOfPlane,并且都实现IValueConverter这个接口,写代码的时间可以直接在IValueConverter上面右击,实现接口,要实现的方法就能搞定了,剩余的就是一些算法。
代码如下:
//TypeConverter
publicclassPlaneConVerter:
IValueConverter
//单向绑定
publicobjectConvert(objectvalue,TypetargetType,objectparameter,System.Globalization.CultureInfoculture)
return@"
\Icons\"
+value.ToString()+"
.png"
publicobjectConvertBack(objectvalue,TypetargetType,objectparameter,System.Globalization.CultureInfoculture)
thrownewNotImplementedException();
publicclassStateOfPlane:
IValueConverter
//双向绑定
//源向目标的转化
switch(value.ToString())
case"
:
returntrue;
returnfalse;
default:
returnnull;
//目标向源的转化
bool?
s=(bool?
)value;
switch(s)
casetrue:
return"
casefalse:
casenull:
C、前后台代码:
XAML
Chapter_04.ConvertInBinding"
local="
clr-namespace:
Chapter_04"
ConvertInBinding"
250"
Window.Resources>
local:
PlaneConVerterx:
Key="
pcv"
/>
StateOfPlanex:
sop"
/Window.Resources>
ListBoxx:
listBox"
160"
ListBox.ItemTemplate>
DataTemplate>
StackPanelOrientation="
Horizontal"
Background="
Beige"
ImageWidth="
25"
30"
Source="
{BindingPath=Category,Converter={StaticResourcepcv}}"
TextBlockText="
{BindingPath=Area}"
60"
CheckBoxIsThreeState="
True"
IsChecked="
{BindingPath=State,Converter={StaticResourcesop}}"
/DataTemplate>
/ListBox.ItemTemplate>
/ListBox>
ButtonContent="
load"
Click="
Button_Click"
/>
SaveInfo"
Button_Click_1"
cs
usingSystem.Collections.ObjectModel;
usingSystem.IO;
///ConvertInBinding.xaml的交互逻辑
publicpartialclassConvertInBinding:
publicConvertInBinding()
privatevoidButton_Click(objectsender,RoutedEventArgse)
ObservableCollection<
Plane>
planeList=newObservableCollection<
()
newPlane{Category="
歼7B"
Area="
济南军区"
State="
},
歼8F"
兰州军区"
成都军区"
南京军区"
};
this.listBox.ItemsSource=planeList;
privatevoidButton_Click_1(objectsender,RoutedEventArgse)
StringBuildersb=newStringBuilder();
foreach(PlanepinlistBox.Items)
sb.AppendLine(string.Format("
Category={0},Area={1},State={2}"
p.Category,p.Area,p.State));
File.WriteAllText(@"
E:
\WPFCode\Chapter_04\PlaneList.txt"
sb.ToString());
最后实现的结果为图2:
图2
其中load按钮时实现装载数据,SaveInfo按钮是保存飞机安排的情况。
下面解释一下上面的例子的重点代码,IValueConverter接口有两个方法,如果是实现源到目标的单向绑定的转化话,直接实现Convert(objectvalue,TypetargetType,objectparameter,CultureInfoculture)方法;
如果是要实现双向绑定的转化,两个方法都要重写,所以还要实现它ConvertBack(objectvalue,TypetargetType,objectparameter,CultureInfoculture)方法。
Converter是绑定的一个属性,所以在<
里面直接为Converter赋值显得很自然了。
二、多路Binding(MultiBinding)
多路Binding主要用于:
一个UI需要显示的信息不止一个数据来决定,MultiBinding有一个属性为Bindings,就是用来添加Binding的。
同时,多路Binding也有Converter属性。
但实现的是IMultiValueConverter接口,方法不一样的地方就是Convert(object[]values,TypetargetType,objectparameter,System.Globalization.CultureInfoculture)里面的第一个参数是复数形式,分别是Binding的源的属性值。
还是通过例子来说明多路绑定的应用吧。
需求是一个按钮是否可用取决于两个文本框的值是否一样。
MultiBindingOfbind.MainWindow"
139"
383"
Vertical"
102"
TextBoxHeight="
23"
HorizontalAlignment="
Left"
Name="
textBox1"
VerticalAlignment="
Top"
350"
textBox2"
Submit"
IsEnabled="
False"
button1"
75"
us