Silverlight 4+WCF RIA ServiceS商业应用 4---Custom DataForm&ChangeTheme
2010-04-21 18:59
489 查看
part1: 如何使用RIA Services
part2: RIA Services更新和验证
part3:RIA Services数据新增
part4:皮肤的更改
part5:报表的展示
part6:Endpoint的设置
part7:如何使用RIA Service Class Library
part8:url重写和界面友好
1. Custom Dataform用来新增一条记录。
前面那篇文章已经提到使用自定义DataForm来新增记录。可能你会觉得自定义DataForm干嘛,直接使用TextBlock和TextBox就行。
自定义一个Dataform可以让数据的验证更容易的实现。
A. 先定义一个CustomRestaurant类,它继承了那面这两个接口。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/07e3ca6a369dce0562a755cd265a3622.gif)
下面那么多属性就是我们需要填写的所有字段。
然后我们添加一个验证规则是Name字段必须不为空且大于4个字符串。
public string this[string columnName]
{
get
{
string result = null;
if (columnName == "Name")
{
if (String.IsNullOrEmpty(Name))
result = "Firstname has to be set!";
else if (Name.Length < 3)
result = "Firstname's length has to be at least 5 characters!";
}
return result;
B. 创建一个自定义控件,它的结构如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/00a05259f914cdfadab3cec91324a230.gif)
这里使用了两个DependencyProperty,第一个是是否编辑,第二个是让TheRestaurant作为它的一个属性。
我们这里使用Resource Dictionary来存放模板信息:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/f4eb3f4b3895b76b5ef096a73c4d63c4.gif)
定义DataForm的模板如下:
<Style TargetType="local:CusRestuarantDataForm">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CusRestuarantDataForm">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="3" Width="{TemplateBinding Width}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<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="150"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0"
Text="Address:" Style="{StaticResource tb}" />
<TextBox Grid.Column="1" Grid.Row="0" x:Name="tAddress" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Address, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="1"
Text="Code:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="1" x:Name="tCode" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Code, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="ContactName:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="2" x:Name="tContactName" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.ContactName, Mode=TwoWay}" IsReadOnly="{Binding IsLocked}" />
<TextBlock Grid.Column="0" Grid.Row="3" Text="ContactTitle:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="3" x:Name="tContactTitle" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.ContactTitle, Mode=TwoWay, TargetNullValue=Doctor}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="4"
Text="Fax:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="4" x:Name="tFax" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Fax, Mode=TwoWay}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="5" Text="ID:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="5" x:Name="tID" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.ID, Mode=TwoWay}"
AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="6" Text="Name:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="6" x:Name="tName" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Name, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="7" Text="Phone:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="7" x:Name="tPhone" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Phone, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="8" Text="Region:"
Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="8" x:Name="tRegion" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Region, Mode=TwoWay, TargetNullValue=Beijing, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
因为这个是自定义Dataform我们还可以使用数据绑定功能来让此DataForm作为查看每条记录的容器,只需要绑定RIA Service的数据源。
先说如何新增记录吧
需要创建一个子窗体。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/581eff964446d22e8c314bbe043390a2.gif)
在Home.xaml页面添加一个Add Record按钮:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/9116f46c020d79637c02462e581c4c69.gif)
Click事件如下:
NewRestuarant cw = new NewRestuarant();
CusRestuarantDataForm custDataform = new CusRestuarantDataForm();
custDataform.Margin = new Thickness(3);
custDataform.Width = 450;
custDataform.TheRestaurant = new CustomRstaurant();
custDataform.IsLocked = false;
cw.LayoutRoot.Children.Add(custDataform);
cw.HasCloseButton = false;
cw.Title = "New Restuarant Detail";
cw.Closed += (s, args) =>
{
if (cw.DialogResult.Value && custDataform.IsValid)
{
}
};
cw.Closing += (s, args) =>
{
if (!custDataform.IsValid && cw.DialogResult.Value)
{
MessageBox.Show("Some of field values are not valid.");
args.Cancel = true;
}
};
cw.Show();
运行一下,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/338d70c56081e0814a0680b55c83be4e.gif)
最后一步是如何使用RIA Service更新数据源了。
在Closed事件发生后加入如下代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/5ed2c581c6f429fb2bbcc64de667da76.gif)
2. 使用SilverlightControlToolkit中的皮肤。
这里需要使用到ICommand方法。
先创建一个Class:
public class ThemeChangeCommand :ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
Theme themeContainer = (Theme)((FrameworkElement)((ContentControl)Application.Current.RootVisual).Content).FindName("ThemeContainer");
string themeName = parameter as string;
if (themeName == null)
{
themeContainer.ThemeUri = null;
}
else
{
themeContainer.ThemeUri =new Uri("/System.Windows.Controls.Theming." + themeName + ";component/Theme.xaml", UriKind.RelativeOrAbsolute);
}
if (CanExecuteChanged != null)
CanExecuteChanged(this, new EventArgs());
}
}
第二步我们需要在APP.xaml中添加如下一句话:
<helper:ThemeChangeCommand x:Key="themeCommand" />
最后就是修改MainPage.xaml中的Contentborder部分。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/ed09869401336adfdc644a5fba0a63ff.gif)
运行一下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/b9d5e7511cd06320de568cd2f654e945.gif)
右键鼠标就能看到不同的皮肤了。选择个黑色的试试:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/c303c039fb6c7dbe42f9a049323e8e0d.gif)
前提是你安装了最新的Silverlight Toolkit。
Reference: http://weblogs.asp.net/fredriknormen/archive/2009/08/10/how-submitchanges-works-in-net-ria-servies.aspx
part2: RIA Services更新和验证
part3:RIA Services数据新增
part4:皮肤的更改
part5:报表的展示
part6:Endpoint的设置
part7:如何使用RIA Service Class Library
part8:url重写和界面友好
1. Custom Dataform用来新增一条记录。
前面那篇文章已经提到使用自定义DataForm来新增记录。可能你会觉得自定义DataForm干嘛,直接使用TextBlock和TextBox就行。
自定义一个Dataform可以让数据的验证更容易的实现。
A. 先定义一个CustomRestaurant类,它继承了那面这两个接口。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/07e3ca6a369dce0562a755cd265a3622.gif)
下面那么多属性就是我们需要填写的所有字段。
然后我们添加一个验证规则是Name字段必须不为空且大于4个字符串。
public string this[string columnName]
{
get
{
string result = null;
if (columnName == "Name")
{
if (String.IsNullOrEmpty(Name))
result = "Firstname has to be set!";
else if (Name.Length < 3)
result = "Firstname's length has to be at least 5 characters!";
}
return result;
B. 创建一个自定义控件,它的结构如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/00a05259f914cdfadab3cec91324a230.gif)
这里使用了两个DependencyProperty,第一个是是否编辑,第二个是让TheRestaurant作为它的一个属性。
我们这里使用Resource Dictionary来存放模板信息:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/f4eb3f4b3895b76b5ef096a73c4d63c4.gif)
定义DataForm的模板如下:
<Style TargetType="local:CusRestuarantDataForm">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CusRestuarantDataForm">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="3" Width="{TemplateBinding Width}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<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="150"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0"
Text="Address:" Style="{StaticResource tb}" />
<TextBox Grid.Column="1" Grid.Row="0" x:Name="tAddress" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Address, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="1"
Text="Code:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="1" x:Name="tCode" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Code, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="ContactName:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="2" x:Name="tContactName" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.ContactName, Mode=TwoWay}" IsReadOnly="{Binding IsLocked}" />
<TextBlock Grid.Column="0" Grid.Row="3" Text="ContactTitle:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="3" x:Name="tContactTitle" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.ContactTitle, Mode=TwoWay, TargetNullValue=Doctor}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="4"
Text="Fax:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="4" x:Name="tFax" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Fax, Mode=TwoWay}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="5" Text="ID:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="5" x:Name="tID" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.ID, Mode=TwoWay}"
AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="6" Text="Name:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="6" x:Name="tName" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Name, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="7" Text="Phone:" Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="7" x:Name="tPhone" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Phone, Mode=TwoWay, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
<TextBlock Grid.Column="0" Grid.Row="8" Text="Region:"
Style="{StaticResource tb}"/>
<TextBox Grid.Column="1" Grid.Row="8" x:Name="tRegion" Style="{StaticResource tx}"
Text="{Binding Path=TheRestaurant.Region, Mode=TwoWay, TargetNullValue=Beijing, ValidatesOnDataErrors=True}" IsReadOnly="{Binding IsLocked}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
因为这个是自定义Dataform我们还可以使用数据绑定功能来让此DataForm作为查看每条记录的容器,只需要绑定RIA Service的数据源。
先说如何新增记录吧
需要创建一个子窗体。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/581eff964446d22e8c314bbe043390a2.gif)
在Home.xaml页面添加一个Add Record按钮:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/9116f46c020d79637c02462e581c4c69.gif)
Click事件如下:
NewRestuarant cw = new NewRestuarant();
CusRestuarantDataForm custDataform = new CusRestuarantDataForm();
custDataform.Margin = new Thickness(3);
custDataform.Width = 450;
custDataform.TheRestaurant = new CustomRstaurant();
custDataform.IsLocked = false;
cw.LayoutRoot.Children.Add(custDataform);
cw.HasCloseButton = false;
cw.Title = "New Restuarant Detail";
cw.Closed += (s, args) =>
{
if (cw.DialogResult.Value && custDataform.IsValid)
{
}
};
cw.Closing += (s, args) =>
{
if (!custDataform.IsValid && cw.DialogResult.Value)
{
MessageBox.Show("Some of field values are not valid.");
args.Cancel = true;
}
};
cw.Show();
运行一下,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/338d70c56081e0814a0680b55c83be4e.gif)
最后一步是如何使用RIA Service更新数据源了。
在Closed事件发生后加入如下代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/5ed2c581c6f429fb2bbcc64de667da76.gif)
2. 使用SilverlightControlToolkit中的皮肤。
这里需要使用到ICommand方法。
先创建一个Class:
public class ThemeChangeCommand :ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
Theme themeContainer = (Theme)((FrameworkElement)((ContentControl)Application.Current.RootVisual).Content).FindName("ThemeContainer");
string themeName = parameter as string;
if (themeName == null)
{
themeContainer.ThemeUri = null;
}
else
{
themeContainer.ThemeUri =new Uri("/System.Windows.Controls.Theming." + themeName + ";component/Theme.xaml", UriKind.RelativeOrAbsolute);
}
if (CanExecuteChanged != null)
CanExecuteChanged(this, new EventArgs());
}
}
第二步我们需要在APP.xaml中添加如下一句话:
<helper:ThemeChangeCommand x:Key="themeCommand" />
最后就是修改MainPage.xaml中的Contentborder部分。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/ed09869401336adfdc644a5fba0a63ff.gif)
运行一下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/b9d5e7511cd06320de568cd2f654e945.gif)
右键鼠标就能看到不同的皮肤了。选择个黑色的试试:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/12/c303c039fb6c7dbe42f9a049323e8e0d.gif)
前提是你安装了最新的Silverlight Toolkit。
Reference: http://weblogs.asp.net/fredriknormen/archive/2009/08/10/how-submitchanges-works-in-net-ria-servies.aspx
相关文章推荐
- Silverlight 4 + RIA Services之商业应用系列----3 DataForm使用
- Silverlight 4 + RIA Services之商业应用系列----2 Updating&Validation
- LR的web_url、web_custom_request、web_submit_data、web_submit_form应用实例
- Silverlight企业应用框架设计【六】自定义系统菜单(使用自己的DataForm)
- 上传文件到服务器时,getParamter()方法 与表单 enctype="multipart/form-data"属性
- WinCE7.0 & VS2008 开发 Silverlight 应用环境搭建
- 上传文件form表单enctype="multipart/form-data"传值解决办法(代原代码)
- Silverlight 4 + RIA Services之商业应用系列
- 解决当FORM的ENCTYPE="multipart/form-data" 时request.getParameter()获取不到值的方法
- form enctype:"multipart/form-data",method:"post" 提交表单,后台获取不到数据
- Silverlight实例教程 – Datagrid,Dataform数据验证和ValidationSummary
- 《开源合辑-企业应用->商业智能(BI)》 第2部分
- 解决当FORM的ENCTYPE="multipart/form-data" 时request.getParameter()获取不到值的方法 ?
- java 页面上有ENCTYPE="multipart/form-data" 时action方法或者控制层用request.getParameter()获取不到值的方法
- Silverlight实例教程 – Datagrid,Dataform数据验证和ValidationSummary
- 【asp】web做文件上传,需要在表单用上 <form Enctype="multipart/form-data"/>
- python post请求实例 & json -- str互相转化(application/x-www-form-urlencoded \ multipart/form-data)
- 错误:invalid use of non-static data member 'main_form::zhiliu_datainfo'
- 解决当FORM的ENCTYPE="multipart/form-data" 时request.getParameter()获取不到值的方法
- C#版的MsMultiPartFormData(适用于Silverlight平台上传二进流数据到服务器)