我不像有些大牛能出书做MVP,有些大牛能卖组件开公司,我只是个小程序员。 今天主要是展示Silverlight的验证和OOB(Out Of Browser)模式,对了,我平时最恨那些写博客只写简写而不注明全称的人,所以这里OOB就是Out Of Browser。顾名思义,浏览器外,也就是Silverlight运行在浏览器外。OK,废话不多说,先上一张图,档案信
我不像有些大牛能出书做MVP,有些大牛能卖组件开公司,我只是个小程序员。
今天主要是展示Silverlight的验证和OOB(Out Of Browser)模式,对了,我平时最恨那些写博客只写简写而不注明全称的人,所以这里OOB就是Out Of Browser。顾名思义,浏览器外,也就是Silverlight运行在浏览器外。OK,废话不多说,先上一张图,档案信息的修改界面。
点击修改按钮,弹出档案信息修改界面。我们首先看看修改界面的UI代码。
<controls:ChildWindow x:Class="MISInfoManage.ArchiveInfoModify"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Width="480" Height="260"
xmlns:LocalResource="clr-namespace:MISInfoManage.Resources">
<controls:ChildWindow.Resources>
<LocalResource:ArchiveInfoModifyResource x:Key="LocalResource"/>
<Style x:Key="TitleColumnStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="12"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</controls:ChildWindow.Resources>
<Grid x:Name="LayoutRoot" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Tb_ArchiveNo,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="0" Grid.Column="0"/>
<TextBox Text="{Binding ArchiveNo,Mode=TwoWay}" Grid.Row="0" Grid.Column="1" FontSize="12" Width="150"/>
<TextBlock Text="{Binding Tb_Name,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="0" Grid.Column="2" Margin="20,0,0,0"/>
<TextBox Text="{Binding Name,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True,UpdateSourceTrigger=Explicit}" Grid.Row="0" Grid.Column="3" FontSize="12" Width="170"/>
<TextBlock Text="{Binding Tb_IdCardNo,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="1" Grid.Column="0" Margin="0,5,0,0"/>
<TextBox Text="{Binding IdCardNo,Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True}" Grid.Row="1" Grid.Column="1" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_Sex,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="1" Grid.Column="2" Margin="20,5,0,0"/>
<ComboBox Grid.Row="1" Grid.Column="3" SelectedValuePath="Tag" SelectedValue="{Binding Sex,Mode=TwoWay}" Margin="0,5,0,0" FontSize="12">
<ComboBoxItem Content="男" Tag="1"></ComboBoxItem>
<ComboBoxItem Content="女" Tag="0"></ComboBoxItem>
</ComboBox>
<TextBlock Text="{Binding Tb_Birth,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="2" Grid.Column="0"/>
<sdk:DatePicker Grid.Row="2" Grid.Column="1" SelectedDate="{Binding BirthDay,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_TelNo,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="20,5,0,0" Grid.Row="2" Grid.Column="2"/>
<TextBox Text="{Binding TelNumber,Mode=TwoWay}" Grid.Row="2" Grid.Column="3" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_Professional,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="3" Grid.Column="0"/>
<TextBox Text="{Binding Professional,Mode=TwoWay}" Grid.Row="3" Grid.Column="1" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_Education,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="20,5,0,0" Grid.Row="3" Grid.Column="2"/>
<ComboBox ItemsSource="{Binding EducationList,Mode=OneWay}" DisplayMemberPath="display_content" SelectedValuePath="data" SelectedValue="{Binding Education,Mode=TwoWay}" FontSize="12" Margin="0,5,0,0" Grid.Row="3" Grid.Column="3"/>
<TextBlock Text="{Binding Tb_GraduateSchool,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="4" Grid.Column="0"/>
<TextBox Text="{Binding GraduateSchool,Mode=TwoWay}" Grid.Row="4" Grid.Column="1" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_GraduateYear,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="20,5,0,0" Grid.Row="4" Grid.Column="2"/>
<TextBox Text="{Binding GraduateYear,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}" Grid.Row="4" Grid.Column="3" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_ArchiveState,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="5" Grid.Column="0"/>
<ComboBox Grid.Row="5" Grid.Column="1" SelectedValuePath="Tag" SelectedValue="{Binding ArchiveState,Mode=TwoWay}" Margin="0,5,0,0" FontSize="12">
<ComboBoxItem Content="已提" Tag="0"/>
<ComboBoxItem Content="在库" Tag="1"/>
</ComboBox>
<StackPanel Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="4" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
<Button Content="{Binding Btn_Modify,Source={StaticResource LocalResource}}" Width="80" Height="25" Margin="0,0,10,0" Click="Button_Click" Tag="m"/>
<Button Content="{Binding Btn_Cancel,Source={StaticResource LocalResource}}" Width="80" Height="25" Click="Button_Click" Tag="c"/>
</StackPanel>
</Grid>
</controls:ChildWindow>
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Width="480" Height="260"
xmlns:LocalResource="clr-namespace:MISInfoManage.Resources">
<controls:ChildWindow.Resources>
<LocalResource:ArchiveInfoModifyResource x:Key="LocalResource"/>
<Style x:Key="TitleColumnStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="12"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</controls:ChildWindow.Resources>
<Grid x:Name="LayoutRoot" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Tb_ArchiveNo,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="0" Grid.Column="0"/>
<TextBox Text="{Binding ArchiveNo,Mode=TwoWay}" Grid.Row="0" Grid.Column="1" FontSize="12" Width="150"/>
<TextBlock Text="{Binding Tb_Name,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="0" Grid.Column="2" Margin="20,0,0,0"/>
<TextBox Text="{Binding Name,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True,UpdateSourceTrigger=Explicit}" Grid.Row="0" Grid.Column="3" FontSize="12" Width="170"/>
<TextBlock Text="{Binding Tb_IdCardNo,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="1" Grid.Column="0" Margin="0,5,0,0"/>
<TextBox Text="{Binding IdCardNo,Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True}" Grid.Row="1" Grid.Column="1" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_Sex,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Grid.Row="1" Grid.Column="2" Margin="20,5,0,0"/>
<ComboBox Grid.Row="1" Grid.Column="3" SelectedValuePath="Tag" SelectedValue="{Binding Sex,Mode=TwoWay}" Margin="0,5,0,0" FontSize="12">
<ComboBoxItem Content="男" Tag="1"></ComboBoxItem>
<ComboBoxItem Content="女" Tag="0"></ComboBoxItem>
</ComboBox>
<TextBlock Text="{Binding Tb_Birth,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="2" Grid.Column="0"/>
<sdk:DatePicker Grid.Row="2" Grid.Column="1" SelectedDate="{Binding BirthDay,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_TelNo,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="20,5,0,0" Grid.Row="2" Grid.Column="2"/>
<TextBox Text="{Binding TelNumber,Mode=TwoWay}" Grid.Row="2" Grid.Column="3" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_Professional,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="3" Grid.Column="0"/>
<TextBox Text="{Binding Professional,Mode=TwoWay}" Grid.Row="3" Grid.Column="1" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_Education,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="20,5,0,0" Grid.Row="3" Grid.Column="2"/>
<ComboBox ItemsSource="{Binding EducationList,Mode=OneWay}" DisplayMemberPath="display_content" SelectedValuePath="data" SelectedValue="{Binding Education,Mode=TwoWay}" FontSize="12" Margin="0,5,0,0" Grid.Row="3" Grid.Column="3"/>
<TextBlock Text="{Binding Tb_GraduateSchool,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="4" Grid.Column="0"/>
<TextBox Text="{Binding GraduateSchool,Mode=TwoWay}" Grid.Row="4" Grid.Column="1" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_GraduateYear,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="20,5,0,0" Grid.Row="4" Grid.Column="2"/>
<TextBox Text="{Binding GraduateYear,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}" Grid.Row="4" Grid.Column="3" Margin="0,5,0,0" FontSize="12"/>
<TextBlock Text="{Binding Tb_ArchiveState,Source={StaticResource LocalResource}}" Style="{StaticResource TitleColumnStyle}" Margin="0,5,0,0" Grid.Row="5" Grid.Column="0"/>
<ComboBox Grid.Row="5" Grid.Column="1" SelectedValuePath="Tag" SelectedValue="{Binding ArchiveState,Mode=TwoWay}" Margin="0,5,0,0" FontSize="12">
<ComboBoxItem Content="已提" Tag="0"/>
<ComboBoxItem Content="在库" Tag="1"/>
</ComboBox>
<StackPanel Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="4" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
<Button Content="{Binding Btn_Modify,Source={StaticResource LocalResource}}" Width="80" Height="25" Margin="0,0,10,0" Click="Button_Click" Tag="m"/>
<Button Content="{Binding Btn_Cancel,Source={StaticResource LocalResource}}" Width="80" Height="25" Click="Button_Click" Tag="c"/>
</StackPanel>
</Grid>
</controls:ChildWindow>
大家看到了,也是Grid和StackPanel布局。我们看到里面有这样一段代码
<ComboBox Grid.Row="1" Grid.Column="3" SelectedValuePath="Tag" SelectedValue="{Binding Sex,Mode=TwoWay}" Margin="0,5,0,0" FontSize="12">
<ComboBoxItem Content="男" Tag="1"></ComboBoxItem>
<ComboBoxItem Content="女" Tag="0"></ComboBoxItem>
</ComboBox>
<ComboBoxItem Content="男" Tag="1"></ComboBoxItem>
<ComboBoxItem Content="女" Tag="0"></ComboBoxItem>
</ComboBox>
注意,这里SelectedValuePath="Tag",这里指定了这个下拉列表的SelectedValue值绑定的是自己的ComboBoxItem 的Tag属性。如果选择了男,下拉列表的SelectedValue值就是1,如果选择女,则SelectedValue值是0。也就是这里绑定的SelectedValue="{Binding Sex,Mode=TwoWay}" ,即ViewModel的Sex属性。
再往下看有这么一段代码
<TextBox Text="{Binding Name,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}" Grid.Row="0" Grid.Column="3" FontSize="12" Width="170"/>
在这里绑定的是ViewModel的Name属性,NotifyOnValidationError和ValidatesOnExceptions用来捕获验证出现的异常。我们来看看ViewModel的代码
namespace ViewModel { public class ArchiveInfoModifyModel { public string ArchiveNo{ get ; set ;} private string archiveState; public string ArchiveState { get { return archiveState;} set { archiveSt
namespace ViewModel
{
public class ArchiveInfoModifyModel
{
public string ArchiveNo { get; set; }
private string archiveState;
public string ArchiveState
{
get { return archiveState; }
set
{
archiveState = value;
NotifyPropertyChange("ArchiveState");
}
}
private string sex;
public string Sex
{
get { return sex; }
set
{
sex = value;
NotifyPropertyChange("Sex");
}
}
private string education { get; set; }
public string Education
{
get { return education; }
set
{
education = value;
NotifyPropertyChange("Education");
}
}
private DateTime? birthDay;
public DateTime? BirthDay
{
get { return birthDay; }
set
{
birthDay = value;
if (value > DateTime.Now.AddYears(-15) || value < DateTime.Now.AddYears(-50))
{
throw new ValidationException("出生日期不正确!");
}
NotifyPropertyChange("BirthDay");
}
}
private string professional;
public string Professional
{
get { return professional; }
set
{
professional = value;
NotifyPropertyChange("Professional");
}
}
private int? graduateYear;
[Range(1950,2012,ErrorMessage="毕业年份不正确!")]
public int? GraduateYear
{
get { return graduateYear; }
set
{
var validatorContext = new ValidationContext(this, null, null);
validatorContext.MemberName = "GraduateYear";
Validator.ValidateProperty(value, validatorContext);
graduateYear = value;
NotifyPropertyChange("GraduateYear");
}
}
private string name;
[Required(ErrorMessage="姓名不能为空!")]
[StringLength(8,ErrorMessage="姓名长度不能超过8!")]
public string Name
{
get { return name; }
set
{
var validatorContext = new ValidationContext(this, null, null);
validatorContext.MemberName = "Name";
Validator.ValidateProperty(value, validatorContext);
name = value;
NotifyPropertyChange("Name");
}
}
private string idCardNo;
public string IdCardNo
{
get { return idCardNo; }
set
{
idCardNo = value;
NotifyPropertyChange("IdCardNo");
}
}
private string graduateSchool;
public string GraduateSchool
{
get { return graduateSchool; }
set
{
graduateSchool = value;
NotifyPropertyChange("GraduateSchool");
}
}
private string telNumber;
public string TelNumber
{
get
{
return telNumber;
}
set
{
telNumber = value;
NotifyPropertyChange("TelNumber");
}
}
private ObservableCollection<ViewModel.ArchiveInfoService.Codes> educationList;
public ObservableCollection<ViewModel.ArchiveInfoService.Codes> EducationList
{
get
{
return educationList;
}
set
{
educationList = value;
NotifyPropertyChange("EducationList");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChange(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
{
public class ArchiveInfoModifyModel
{
public string ArchiveNo { get; set; }
private string archiveState;
public string ArchiveState
{
get { return archiveState; }
set
{
archiveState = value;
NotifyPropertyChange("ArchiveState");
}
}
private string sex;
public string Sex
{
get { return sex; }
set
{
sex = value;
NotifyPropertyChange("Sex");
}
}
private string education { get; set; }
public string Education
{
get { return education; }
set
{
education = value;
NotifyPropertyChange("Education");
}
}
private DateTime? birthDay;
public DateTime? BirthDay
{
get { return birthDay; }
set
{
birthDay = value;
if (value > DateTime.Now.AddYears(-15) || value < DateTime.Now.AddYears(-50))
{
throw new ValidationException("出生日期不正确!");
}
NotifyPropertyChange("BirthDay");
}
}
private string professional;
public string Professional
{
get { return professional; }
set
{
professional = value;
NotifyPropertyChange("Professional");
}
}
private int? graduateYear;
[Range(1950,2012,ErrorMessage="毕业年份不正确!")]
public int? GraduateYear
{
get { return graduateYear; }
set
{
var validatorContext = new ValidationContext(this, null, null);
validatorContext.MemberName = "GraduateYear";
Validator.ValidateProperty(value, validatorContext);
graduateYear = value;
NotifyPropertyChange("GraduateYear");
}
}
private string name;
[Required(ErrorMessage="姓名不能为空!")]
[StringLength(8,ErrorMessage="姓名长度不能超过8!")]
public string Name
{
get { return name; }
set
{
var validatorContext = new ValidationContext(this, null, null);
validatorContext.MemberName = "Name";
Validator.ValidateProperty(value, validatorContext);
name = value;
NotifyPropertyChange("Name");
}
}
private string idCardNo;
public string IdCardNo
{
get { return idCardNo; }
set
{
idCardNo = value;
NotifyPropertyChange("IdCardNo");
}
}
private string graduateSchool;
public string GraduateSchool
{
get { return graduateSchool; }
set
{
graduateSchool = value;
NotifyPropertyChange("GraduateSchool");
}
}
private string telNumber;
public string TelNumber
{
get
{
return telNumber;
}
set
{
telNumber = value;
NotifyPropertyChange("TelNumber");
}
}
private ObservableCollection<ViewModel.ArchiveInfoService.Codes> educationList;
public ObservableCollection<ViewModel.ArchiveInfoService.Codes> EducationList
{
get
{
return educationList;
}
set
{
educationList = value;
NotifyPropertyChange("EducationList");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChange(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
我们看到了Name和GraduateYear等加入了验证。Name验证了非空和长度,采用的是标注Attribute的格式,和MVC的验证方式一样,需要引入System.ComponentModel.DataAnnotations命名空间。其中的Birthday属性采用了抛出异常的方式,当抛出异常后,页面UI会接收到异常信息,并显示红色的提示信息,因为Birthday设置了ValidatesOnExceptions=True。我们来看看验证的效果。
UI会提示出生日期不正确。如果毕业年份输入不正确,也会给出提示信息。
因为毕业年份设置了NotifyOnValidationError=True。所以在这里NotifyOnValidationError对应于设置ValidationAttribute的方式,而ValidatesOnExceptions对应于Set访问器中的抛出异常方式。在这里我特别要注意说明的是
<TextBox Text="{Binding Name,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True,UpdateSourceTrigger=Explicit}" Grid.Row="0" Grid.Column="3" FontSize="12" Width="170"/>
在这里有一个UpdateSourceTrigger,这个属性有两个值,一个是默认的Default,一个是Explicit,有什么区别呢?我们在用MVVM的时候,经常会碰到这样一种场景,在文本框输入一个值,然后直接按回车键查数据或者别的什么
在这里有一个UpdateSourceTrigger,这个属性有两个值,一个是默认的Default,一个是Explicit,有什么区别呢?我们在用MVVM的时候,经常会碰到这样一种场景,在文本框输入一个值,然后直接按回车键查数据或者别的什么操作,但是你会发现回车后取得的文本框得值仍然是文本框上次的值(没有失去焦点前的值)。为什么呢?这就是这里要说的UpdateSourceTrigger,在双向绑定下,大多数控件默认是在PropertyChanged以后就会更改ViewModel的值,但是TextBox则默认是失去焦点以后才会更改ViewModel的值。所以在这里我也不默认了,直接改成UpdateSourceTrigger=Explicit,显式的调用BindingExpression的UpdateSource方法获取页面上的值,将其反映到ViewModel上。这就意味着,只有在在调用了UpdateSource方法以后才会启用验证。上述讲的验证只是在失去焦点以后的验证,大多数情况下我们是要点击提交按钮以后来验证,并且验证不通过,不能再执行下面的逻辑。这个在我们web开发中很容易实现,但是在Silverlight中怎么实现呢?我们看看后台
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Client.Common;
using ViewModel;
namespace MISInfoManage
{
public partial class ArchiveInfoModify : ChildWindow
{
string archiveNo;
ArchiveInfoModifyModel viewModel;
ViewModel.ArchiveInfoService.ArchiveInfoServiceClient client;
public ArchiveInfoModify()
{
InitializeComponent();
this.Title = "档案信息修改";
}
public ArchiveInfoModify(string archiveNo)
: this()
{
this.archiveNo = archiveNo;
viewModel = new ArchiveInfoModifyModel();
this.Loaded += delegate(object sender, RoutedEventArgs e)
{
client = new ViewModel.ArchiveInfoService.ArchiveInfoServiceClient();
client.GetEducationCompleted += delegate(object sender1, ViewModel.ArchiveInfoService.GetEducationCompletedEventArgs e1)
{
viewModel.EducationList = new System.Collections.ObjectModel.ObservableCollection<ViewModel.ArchiveInfoService.Codes>(e1.Result);
this.GetArchiveInfoByNo();
};
client.GetEducationAsync();
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
if (button.Tag.ToString().Equals("m"))
{
if (!this.ValidateData())
{
return;
}
ViewModel.ArchiveInfoService.Person_Info personInfo = new ViewModel.ArchiveInfoService.Person_Info()
{
birth = viewModel.BirthDay.Value,
contact_tel = viewModel.TelNumber,
education_level = viewModel.Education,
graduate_school = viewModel.GraduateSchool,
graduate_year = viewModel.GraduateYear.Value,
id_card = viewModel.IdCardNo,
name = viewModel.Name,
no = viewModel.ArchiveNo,
professional = viewModel.Professional,
sex = viewModel.Sex,
state = viewModel.ArchiveState
};
client.ModifyArchiveInfoCompleted += delegate(object modifySender, ViewModel.ArchiveInfoService.ModifyArchiveInfoCompletedEventArgs modifyArgs)
{
new Thread(() =>
{
UISynchronizationContext.Context.Post((state) =>
{
MessageBox.Show("修改成功!");
}, null);
}).Start();
};
client.ModifyArchiveInfoAsync(personInfo);
}
if (button.Tag.ToString().Equals("c"))
{
this.Close();
}
}
private void GetArchiveInfoByNo()
{
client.GetPersonInfoByIDCompleted += delegate(object sender, ViewModel.ArchiveInfoService.GetPersonInfoByIDCompletedEventArgs e)
{
ViewModel.ArchiveInfoService.Person_Info personInfo = e.Result;
this.viewModel.ArchiveNo = personInfo.no;
this.viewModel.ArchiveState = personInfo.state;
this.viewModel.BirthDay = personInfo.birth;
this.viewModel.Education = personInfo.education_level;
this.viewModel.GraduateSchool = personInfo.graduate_school;
this.viewModel.GraduateYear = personInfo.graduate_year;
this.viewModel.IdCardNo = personInfo.id_card;
this.viewModel.Name = personInfo.name;
this.viewModel.Professional = personInfo.professional;
this.viewModel.Sex = personInfo.sex;
this.viewModel.TelNumber = personInfo.contact_tel;
this.LayoutRoot.DataContext = viewModel;
};
client.GetPersonInfoByIDAsync(archiveNo);
}
private bool ValidateData()
{
UIElementCollection UIElments = LayoutRoot.Children;
foreach (var element in UIElments)
{
if (element.GetType() == typeof(TextBox))
{
TextBox textbox = element as TextBox;
BindingExpression expression = textbox.GetBindingExpression(TextBox.TextProperty);
if (expression.ParentBinding.NotifyOnValidationError == true || expression.ParentBinding.ValidatesOnExceptions == true)
{
expression.UpdateSource();
if (Validation.GetHasError(textbox))
{
return false;
}
}
}
if (element.GetType() == typeof(ComboBox))
{
ComboBox comboBox = element as ComboBox;
BindingExpression expression = comboBox.GetBindingExpression(ComboBox.SelectedValueProperty);
if (expression.ParentBinding.NotifyOnValidationError == true || expression.ParentBinding.ValidatesOnExceptions == true)
{
expression.UpdateSource();
if (Validation.GetHasError(comboBox))
{
return false;
}
}
}
if (element.GetType() == typeof(DatePicker))
{
DatePicker datepicker = element as DatePicker;
BindingExpression expression = datepicker.GetBindingExpression(DatePicker.SelectedDateProperty);
if (expression.ParentBinding.NotifyOnValidationError == true || expression.ParentBinding.ValidatesOnExceptions == true)
{
expression.UpdateSource();
if (Validation.GetHasError(datepicker))
{
return false;
}
}
}
}
return true;
}
}
}
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Client.Common;
using ViewModel;
namespace MISInfoManage
{
public partial class ArchiveInfoModify : ChildWindow
{
string archiveNo;
ArchiveInfoModifyModel viewModel;
ViewModel.ArchiveInfoService.ArchiveInfoServiceClient client;
public ArchiveInfoModify()
{
InitializeComponent();
this.Title = "档案信息修改";
}
public ArchiveInfoModify(string archiveNo)
: this()
{
this.archiveNo = archiveNo;
viewModel = new ArchiveInfoModifyModel();
this.Loaded += delegate(object sender, RoutedEventArgs e)
{
client = new ViewModel.ArchiveInfoService.ArchiveInfoServiceClient();
client.GetEducationCompleted += delegate(object sender1, ViewModel.ArchiveInfoService.GetEducationCompletedEventArgs e1)
{
viewModel.EducationList = new System.Collections.ObjectModel.ObservableCollection<ViewModel.ArchiveInfoService.Codes>(e1.Result);
this.GetArchiveInfoByNo();
};
client.GetEducationAsync();
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
if (button.Tag.ToString().Equals("m"))
{
if (!this.ValidateData())
{
return;
}
ViewModel.ArchiveInfoService.Person_Info personInfo = new ViewModel.ArchiveInfoService.Person_Info()
{
birth = viewModel.BirthDay.Value,
contact_tel = viewModel.TelNumber,
education_level = viewModel.Education,
graduate_school = viewModel.GraduateSchool,
graduate_year = viewModel.GraduateYear.Value,
id_card = viewModel.IdCardNo,
name = viewModel.Name,
no = viewModel.ArchiveNo,
professional = viewModel.Professional,
sex = viewModel.Sex,
state = viewModel.ArchiveState
};
client.ModifyArchiveInfoCompleted += delegate(object modifySender, ViewModel.ArchiveInfoService.ModifyArchiveInfoCompletedEventArgs modifyArgs)
{
new Thread(() =>
{
UISynchronizationContext.Context.Post((state) =>
{
MessageBox.Show("修改成功!");
}, null);
}).Start();
};
client.ModifyArchiveInfoAsync(personInfo);
}
if (button.Tag.ToString().Equals("c"))
{
this.Close();
}
}
private void GetArchiveInfoByNo()
{
client.GetPersonInfoByIDCompleted += delegate(object sender, ViewModel.ArchiveInfoService.GetPersonInfoByIDCompletedEventArgs e)
{
ViewModel.ArchiveInfoService.Person_Info personInfo = e.Result;
this.viewModel.ArchiveNo = personInfo.no;
this.viewModel.ArchiveState = personInfo.state;
this.viewModel.BirthDay = personInfo.birth;
this.viewModel.Education = personInfo.education_level;
this.viewModel.GraduateSchool = personInfo.graduate_school;
this.viewModel.GraduateYear = personInfo.graduate_year;
this.viewModel.IdCardNo = personInfo.id_card;
this.viewModel.Name = personInfo.name;
this.viewModel.Professional = personInfo.professional;
this.viewModel.Sex = personInfo.sex;
this.viewModel.TelNumber = personInfo.contact_tel;
this.LayoutRoot.DataContext = viewModel;
};
client.GetPersonInfoByIDAsync(archiveNo);
}
private bool ValidateData()
{
UIElementCollection UIElments = LayoutRoot.Children;
foreach (var element in UIElments)
{
if (element.GetType() == typeof(TextBox))
{
TextBox textbox = element as TextBox;
BindingExpression expression = textbox.GetBindingExpression(TextBox.TextProperty);
if (expression.ParentBinding.NotifyOnValidationError == true || expression.ParentBinding.ValidatesOnExceptions == true)
{
expression.UpdateSource();
if (Validation.GetHasError(textbox))
{
return false;
}
}
}
if (element.GetType() == typeof(ComboBox))
{
ComboBox comboBox = element as ComboBox;
BindingExpression expression = comboBox.GetBindingExpression(ComboBox.SelectedValueProperty);
if (expression.ParentBinding.NotifyOnValidationError == true || expression.ParentBinding.ValidatesOnExceptions == true)
{
expression.UpdateSource();
if (Validation.GetHasError(comboBox))
{
return false;
}
}
}
if (element.GetType() == typeof(DatePicker))
{
DatePicker datepicker = element as DatePicker;
BindingExpression expression = datepicker.GetBindingExpression(DatePicker.SelectedDateProperty);
if (expression.ParentBinding.NotifyOnValidationError == true || expression.ParentBinding.ValidatesOnExceptions == true)
{
expression.UpdateSource();
if (Validation.GetHasError(datepicker))
{
return false;
}
}
}
}
return true;
}
}
}
我们看看这个Button_Click事件,在修改方法中,我们调用了ValidateData方法,该方法循环遍历页面UIElment,并强制更新ViewModel中的值。如果发现验证不通过,直接返回False,在Button_Click事件中,如果没有通过验证,就不再执行修改操作。这样就实现了验证不通过,就不再往下走的逻辑。关于验证,我就说到这里,如有不懂,可以加入.net群205217091,我可以把源代码共享给大家。我们看看服务端代码
public int ModifyArchiveInfo(Person_InfopersonInfoModel) { Person_InfopersonInfo=misInfoEntities.person_info.SingleOrDefault(p=p.no.Equals(personInfoModel.no)); Typetype=personInfo.GetType(); Propert
public int ModifyArchiveInfo(Person_Info personInfoModel)
{
Person_Info personInfo = misInfoEntities.person_info.SingleOrDefault(p => p.no.Equals(personInfoModel.no));
Type type = personInfo.GetType();
PropertyInfo[] propertyInfos = type.GetProperties().Where(p=>!p.Name.Equals("id")).ToArray();
foreach (var propertyInfo in propertyInfos)
{
propertyInfo.SetValue(personInfo, propertyInfo.GetValue(personInfoModel, null));
}
return misInfoEntities.SaveChanges();
}
{
Person_Info personInfo = misInfoEntities.person_info.SingleOrDefault(p => p.no.Equals(personInfoModel.no));
Type type = personInfo.GetType();
PropertyInfo[] propertyInfos = type.GetProperties().Where(p=>!p.Name.Equals("id")).ToArray();
foreach (var propertyInfo in propertyInfos)
{
propertyInfo.SetValue(personInfo, propertyInfo.GetValue(personInfoModel, null));
}
return misInfoEntities.SaveChanges();
}
这个后台代码也没什么,循环遍历利用反射赋值,最后调用DBContext的SaveChanges方法完成更新。好了,最后我们看看OOB模式。
在Silverlight 项目上点击右键,打开属性设置界面,如下所示
我们勾选Enable running application out of browser,然后点击Out-of-Browser Settings按钮,弹出设置界面,如下
我们设置了高度和宽度,以及window style等信息。OK,我们再次将程序运行起来。我们发现点击右键多了一项“将MISInformation Application 安装到此计算机...”。我们点击安装后,出现下面的界面
勾选开始和桌面后,点击确定,我们发现桌面上多了一个图标,如下所示
我们双击它,弹出如下界面,即我们的OOB运行模式
OK,看到了吧,Title是我们上面设置的档案信息管理。怎么样,这样的Silverlight运行方式是不是很不错。它同样能够实现在浏览器中的功能,如下
本文出自 “BruceAndLee” 博客,请务必保留此出处http://leelei.blog.51cto.com/856755/916182
http://silverlightchina.net/html/tips/2012/0709/17252_4.html