Prism应用开发(六)——MVVM高级话题
2016-08-12 09:14
399 查看
一、Commands
Composite Commands
情景:
![](http://my.csdn.net/uploads/201207/11/1341977450_4721.jpg)
上述情景中,Submit All Command的逻辑是要调用所有Submit Command的逻辑。
解决方案: Prism中提供了CompositeCommand,这个类持有一组child command,CompositeCommand在执行的时候将会调用每一个child command的Execute方法,可以通过,可以通过RegisterCommand和UnregisterCommand来注册和注销child command。
[csharp]
view plain
copy
print?
commandProxy.SubmitAllOrdersCommand.RegisterCommand(
orderCompositeViewModel.SubmitCommand );
commandProxy.CancelAllOrdersCommand.RegisterCommand(
orderCompositeViewModel.CancelCommand );
![](http://static.blog.csdn.net/images/save_snippets.png)
在当前View上执行Command
情景:
![](http://my.csdn.net/uploads/201207/11/1341983202_3701.jpg)
在上面的应用中,放大缩小按钮应该只对当前的活动视图(active view)起作用,而对其它视图不起作用。
解决方案: Prism提供了IActiveAware接口,它包含了IsActive属性和IsActiveChanged事件。DelegateCommand实现了这个接口,CompositeCommand下面的构造函数能够使得在执行child command的时候只执行所有的active command。
[csharp]
view plain
copy
print?
public CompositeCommand(bool monitorCommandActivity);
![](http://static.blog.csdn.net/images/save_snippets.png)
集合中的Command
情景:
![](http://my.csdn.net/uploads/201207/11/1341984032_4895.jpg)
这个问题的关键是,在每一个Item中点击“Delete”实际上是改变它的parent view中view model的集合,问题的难点在于,每个Item的data context是集合本身的一项,而不是实现了Delete Command的parent view model。
解决方案:
使用ElementName属性指定绑定是相对于它的parent control,而不是相对于data template。
[html]
view plain
copy
print?
<Grid x:Name="root">
<ListBox ItemsSource="{Binding Path=Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Path=Name}" Command="{Binding ElementName=root,
Path=DataContext.DeleteCommand}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
![](http://static.blog.csdn.net/images/save_snippets.png)
可以使用CommandParameter指明当前应用的item,也可以实现command来获取当前选中的item(通过CollectionView)。
二、交互
在很多时候,应用程序都会通知用户当前状态或者在处理一个请求之前需要用户的确认,在非MVVM模式中,很通用的方式就是在Code-behind文件中使用MessageBox类进行交互,然而在MVVM模式中,这种做法就不合适了,因为这会使得部分view model逻辑放到了view中。
在MVVM模式中,通常有两种方法可以实现这种交互,一种方法是实现一个由view model使用的service来触发用户交互,另一种方法是由view model 触发一个事件来进行交互。
使用Interaction Service
这种方法是使得view model依赖于interaction service进行用户交互,interaction service实现交互的可视化部分。
[csharp]
view plain
copy
print?
var result =
interactionService.ShowMessageBox(
"Are you sure you want to cancel this operation?",
"Confirm",
MessageBoxButton.OK );
if (result == MessageBoxResult.Yes)
{
CancelRequest();
}
![](http://static.blog.csdn.net/images/save_snippets.png)
使用Interaction Request Object
这种方法是view model将交互请求直接发给view本身,请求对象封装封装请求和回复的所有细节,并且通过event和view通信,view通过behavior绑定到view model提供的request object。
Prism采用这种方式,并且提供了IInteractionRequest接口和InteractionRequest<T>类。
[csharp]
view plain
copy
print?
public interface IInteractionRequest
{
event EventHandler<InteractionRequestedEventArgs> Raised;
}
public class InteractionRequest<T> : IInteractionRequest
{
public event EventHandler<InteractionRequestedEventArgs> Raised;
public void Raise(T context, Action<T> callback)
{
var handler = this.Raised;
if (handler != null)
{
handler(
this,
new InteractionRequestedEventArgs(
context,
() => callback(context)));
}
}
}
![](http://static.blog.csdn.net/images/save_snippets.png)
Prism同时提供了上下文类,用作交互传递。Notification类是这些类的基类,Confirmation类继承自Notification用于实现类似MessageBox类型的交互请求。
下面的代码显示了view model如何使用InteractionRequest<T>。
[csharp]
view plain
copy
print?
public IInteractionRequest ConfirmCancelInteractionRequest
{
get
{
return this.confirmCancelInteractionRequest;
}
}
this.confirmCancelInteractionRequest.Raise(
new Confirmation("Are you sure you wish to cancel?"),
confirmation =>
{
if (confirmation.Confirmed)
{
this.NavigateToQuestionnaireList();
}
});
}
![](http://static.blog.csdn.net/images/save_snippets.png)
在view层次,prism提供了InteractionRequestTrigger,这个类能自动连接到IInteractionRequest接口的Raised 事件,
[html]
view plain
copy
print?
<i:Interaction.Triggers>
<prism:InteractionRequestTrigger
SourceObject="{Binding ConfirmCancelInteractionRequest}">
<prism:PopupChildWindowAction
ContentTemplate="{StaticResource ConfirmWindowTemplate}"/>
</prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
<UserControl.Resources>
<DataTemplate x:Key="ConfirmWindowTemplate">
<Grid MinWidth="250" MinHeight="100">
<TextBlock TextWrapping="Wrap" Grid.Row="0" Text="{Binding}"/>
</Grid>
</DataTemplate>
</UserControl.Resources>
Composite Commands
情景:
![](http://my.csdn.net/uploads/201207/11/1341977450_4721.jpg)
上述情景中,Submit All Command的逻辑是要调用所有Submit Command的逻辑。
解决方案: Prism中提供了CompositeCommand,这个类持有一组child command,CompositeCommand在执行的时候将会调用每一个child command的Execute方法,可以通过,可以通过RegisterCommand和UnregisterCommand来注册和注销child command。
[csharp]
view plain
copy
print?
commandProxy.SubmitAllOrdersCommand.RegisterCommand(
orderCompositeViewModel.SubmitCommand );
commandProxy.CancelAllOrdersCommand.RegisterCommand(
orderCompositeViewModel.CancelCommand );
![](http://static.blog.csdn.net/images/save_snippets.png)
commandProxy.SubmitAllOrdersCommand.RegisterCommand( orderCompositeViewModel.SubmitCommand ); commandProxy.CancelAllOrdersCommand.RegisterCommand( orderCompositeViewModel.CancelCommand );
在当前View上执行Command
情景:
![](http://my.csdn.net/uploads/201207/11/1341983202_3701.jpg)
在上面的应用中,放大缩小按钮应该只对当前的活动视图(active view)起作用,而对其它视图不起作用。
解决方案: Prism提供了IActiveAware接口,它包含了IsActive属性和IsActiveChanged事件。DelegateCommand实现了这个接口,CompositeCommand下面的构造函数能够使得在执行child command的时候只执行所有的active command。
[csharp]
view plain
copy
print?
public CompositeCommand(bool monitorCommandActivity);
![](http://static.blog.csdn.net/images/save_snippets.png)
public CompositeCommand(bool monitorCommandActivity);
集合中的Command
情景:
![](http://my.csdn.net/uploads/201207/11/1341984032_4895.jpg)
这个问题的关键是,在每一个Item中点击“Delete”实际上是改变它的parent view中view model的集合,问题的难点在于,每个Item的data context是集合本身的一项,而不是实现了Delete Command的parent view model。
解决方案:
使用ElementName属性指定绑定是相对于它的parent control,而不是相对于data template。
[html]
view plain
copy
print?
<Grid x:Name="root">
<ListBox ItemsSource="{Binding Path=Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Path=Name}" Command="{Binding ElementName=root,
Path=DataContext.DeleteCommand}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
![](http://static.blog.csdn.net/images/save_snippets.png)
<Grid x:Name="root"> <ListBox ItemsSource="{Binding Path=Items}"> <ListBox.ItemTemplate> <DataTemplate> <Button Content="{Binding Path=Name}" Command="{Binding ElementName=root, Path=DataContext.DeleteCommand}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid>
可以使用CommandParameter指明当前应用的item,也可以实现command来获取当前选中的item(通过CollectionView)。
二、交互
在很多时候,应用程序都会通知用户当前状态或者在处理一个请求之前需要用户的确认,在非MVVM模式中,很通用的方式就是在Code-behind文件中使用MessageBox类进行交互,然而在MVVM模式中,这种做法就不合适了,因为这会使得部分view model逻辑放到了view中。
在MVVM模式中,通常有两种方法可以实现这种交互,一种方法是实现一个由view model使用的service来触发用户交互,另一种方法是由view model 触发一个事件来进行交互。
使用Interaction Service
这种方法是使得view model依赖于interaction service进行用户交互,interaction service实现交互的可视化部分。
[csharp]
view plain
copy
print?
var result =
interactionService.ShowMessageBox(
"Are you sure you want to cancel this operation?",
"Confirm",
MessageBoxButton.OK );
if (result == MessageBoxResult.Yes)
{
CancelRequest();
}
![](http://static.blog.csdn.net/images/save_snippets.png)
var result = interactionService.ShowMessageBox( "Are you sure you want to cancel this operation?", "Confirm", MessageBoxButton.OK ); if (result == MessageBoxResult.Yes) { CancelRequest(); }
使用Interaction Request Object
这种方法是view model将交互请求直接发给view本身,请求对象封装封装请求和回复的所有细节,并且通过event和view通信,view通过behavior绑定到view model提供的request object。
Prism采用这种方式,并且提供了IInteractionRequest接口和InteractionRequest<T>类。
[csharp]
view plain
copy
print?
public interface IInteractionRequest
{
event EventHandler<InteractionRequestedEventArgs> Raised;
}
public class InteractionRequest<T> : IInteractionRequest
{
public event EventHandler<InteractionRequestedEventArgs> Raised;
public void Raise(T context, Action<T> callback)
{
var handler = this.Raised;
if (handler != null)
{
handler(
this,
new InteractionRequestedEventArgs(
context,
() => callback(context)));
}
}
}
![](http://static.blog.csdn.net/images/save_snippets.png)
public interface IInteractionRequest { event EventHandler<InteractionRequestedEventArgs> Raised; } public class InteractionRequest<T> : IInteractionRequest { public event EventHandler<InteractionRequestedEventArgs> Raised; public void Raise(T context, Action<T> callback) { var handler = this.Raised; if (handler != null) { handler( this, new InteractionRequestedEventArgs( context, () => callback(context))); } } }
Prism同时提供了上下文类,用作交互传递。Notification类是这些类的基类,Confirmation类继承自Notification用于实现类似MessageBox类型的交互请求。
下面的代码显示了view model如何使用InteractionRequest<T>。
[csharp]
view plain
copy
print?
public IInteractionRequest ConfirmCancelInteractionRequest
{
get
{
return this.confirmCancelInteractionRequest;
}
}
this.confirmCancelInteractionRequest.Raise(
new Confirmation("Are you sure you wish to cancel?"),
confirmation =>
{
if (confirmation.Confirmed)
{
this.NavigateToQuestionnaireList();
}
});
}
![](http://static.blog.csdn.net/images/save_snippets.png)
public IInteractionRequest ConfirmCancelInteractionRequest { get { return this.confirmCancelInteractionRequest; } } this.confirmCancelInteractionRequest.Raise( new Confirmation("Are you sure you wish to cancel?"), confirmation => { if (confirmation.Confirmed) { this.NavigateToQuestionnaireList(); } }); }
在view层次,prism提供了InteractionRequestTrigger,这个类能自动连接到IInteractionRequest接口的Raised 事件,
[html]
view plain
copy
print?
<i:Interaction.Triggers>
<prism:InteractionRequestTrigger
SourceObject="{Binding ConfirmCancelInteractionRequest}">
<prism:PopupChildWindowAction
ContentTemplate="{StaticResource ConfirmWindowTemplate}"/>
</prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
<UserControl.Resources>
<DataTemplate x:Key="ConfirmWindowTemplate">
<Grid MinWidth="250" MinHeight="100">
<TextBlock TextWrapping="Wrap" Grid.Row="0" Text="{Binding}"/>
</Grid>
</DataTemplate>
</UserControl.Resources>
相关文章推荐
- Prism应用开发(六)——MVVM高级话题
- Prism应用开发(四)——MVVM模式基础
- Prism应用开发(五)——MVVM模式关键技术
- Prism初研究之使用Prism实现WPF的MVVM的高级应用
- Prism应用开发(四)——MVVM模式基础
- SAP 高级应用开发 学习笔记 1 -- RFC NO.4
- 使用 Dojo 的 Ajax 应用开发进阶教程,第 1 部分: JavaScript 技巧与高级特性
- 重读C#高级编程之Struct在实际开发中的应用
- 使用ArcGIS Mobile SDK 9.3 开发移动设备应用-高级篇
- 应用MFC开发高级应用程序
- jdbc连接各种数据库方式列表 And Servlet开发中JDBC的高级应用
- 对阿尔卡特朗讯实施3天的Linux应用高级开发技术培训
- RIA(Rich Internet Application)应用开发工程师(高级)
- SAP 高级应用开发 学习笔记 1 -- RFC NO.3
- SAP 高级应用开发 学习笔记 1 -- RFC NO.5
- SAP 高级应用开发 学习笔记 2 -- BAPI
- 第六章:高级OAF开发话题---支持浏览器后退按钮
- [转]PHP程序开发范例宝典 -- 第9章 MySQL高级应用技术
- [转]PHP程序开发范例宝典 -- 第9章 MySQL高级应用技术
- SAP 高级应用开发 学习笔记 1 -- RFC