棱镜自定义确认交互
Prism Custom Confirmation Interaction
我使用 Prism Unity、WPF 和 Mvvm 在应用程序中创建了自定义确认 window。我需要有关需要发送回视图模型的通知的帮助。我在详细记录视图中有这个,我们称它为 MyDetailView。
<!-- Custom Confirmation Window -->
<ie:Interaction.Triggers>
<interactionRequest:InteractionRequestTrigger
SourceObject="{Binding ConfirmationRequest, Mode=TwoWay}">
<mycontrols:PopupWindowAction1 IsModal="True"/>
</interactionRequest:InteractionRequestTrigger>
</ie:Interaction.Triggers>
如上所示,我设置了交互 Mode=TwoWay,以便确认弹出窗口 window 可以发回“确定”或“取消”按钮的按钮点击结果。确认 window 按原样出现,但我不知道如何将按钮点击结果发送回我的视图模型,比如 MyDetailViewModel。这是主要问题。
编辑:这是引发 InteractionRequest 的 MyDetailViewMmodel 方法。
private void RaiseConfirmation()
{ConfirmationRequest
.Raise(new Confirmation()
{
Title = "Confirmation Popup",
Content = "Save Changes?"
}, c =>{if (c.Confirmed)
{ UoW.AdrTypeRos.Submit();}
这是 PopupWindowAction1 class。该问题的部分答案可能是我如何实现 Notification 和 FinishedInteraction 方法。
class PopupWindowAction1 : PopupWindowAction, IInteractionRequestAware
{
protected override Window GetWindow(INotification notification)
{ // custom metrowindow using mahapps
MetroWindow wrapperWindow = new ConfirmWindow1();
wrapperWindow.DataContext = notification;
wrapperWindow.Title = notification.Title;
this.PrepareContentForWindow(notification, wrapperWindow);
return wrapperWindow;
}
public INotification Notification
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public Action FinishInteraction
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
是否需要在我的 ConfirmWindow1 中加入一些互动,比如这样的?
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<ei:CallMethodAction
TargetObject="{Binding RelativeSource={RelativeSource AncestorType=UserControl},
Path=DataContext}"
MethodName="DataContext.ValidateConfirm"/>
</i:EventTrigger>
</i:Interaction.Triggers>
我什至需要在按钮中进行这种类型的交互吗?如果是这样,我如何编写它需要的代码,以便它对应于调用交互的特定视图模型。有什么建议么?谢谢。
最主要的是,当你引发交互时,提供一个回调,当交互完成时触发。此回调会返回通知,您的交互应该已将所有可能有趣的 return 值存储在那里。
这是一个例子...
ViewModel 的相关部分:
public InteractionRequest<SelectQuantityNotification> SelectQuantityRequest
{
get;
}
// in some handler that triggers the interaction
SelectQuantityRequest.Raise( new SelectQuantityNotification { Title = "Load how much stuff?", Maximum = maximumQuantity },
notification =>
{
if (notification.Confirmed)
_worldStateService.ExecuteCommand( new LoadCargoCommand( sourceStockpile.Stockpile, cartViewModel.Cart, notification.Quantity ) );
} );
...从视图中:
<i:Interaction.Triggers>
<interactionRequest:InteractionRequestTrigger
SourceObject="{Binding SelectQuantityRequest, Mode=OneWay}">
<framework:FixedSizePopupWindowAction>
<interactionRequest:PopupWindowAction.WindowContent>
<views:SelectSampleDataForImportPopup/>
</interactionRequest:PopupWindowAction.WindowContent>
</framework:FixedSizePopupWindowAction>
</interactionRequest:InteractionRequestTrigger>
</i:Interaction.Triggers>
此外,我们需要一个 class 来保存传递的数据,以及一个 ViewModel/View 对用于交互本身。
这是持有 class 的数据(注意 Maximum
被传递 到 交互,并且 Quantity
returned 来自它):
internal class SelectQuantityNotification : Confirmation
{
public int Maximum
{
get;
set;
}
public int Quantity
{
get;
set;
}
}
这是交互弹窗的视图:
<UserControl x:Class="ClientModule.Views.SelectSampleDataForImportPopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Vertical">
<TextBlock>
Amount: <Run Text="{Binding Quantity}"/>
</TextBlock>
<Slider Orientation="Horizontal" Minimum="0" Maximum="{Binding Maximum}" Value="{Binding Quantity}" TickPlacement="BottomRight"/>
<Button Content="Ok" Command="{Binding OkCommand}"/>
</StackPanel>
</UserControl>
它是 ViewModel:
internal class SelectSampleDataForImportPopupViewModel : BindableBase, IInteractionRequestAware
{
public SelectSampleDataForImportPopupViewModel()
{
OkCommand = new DelegateCommand( OnOk );
}
public DelegateCommand OkCommand
{
get;
}
public int Quantity
{
get { return _notification?.Quantity ?? 0; }
set
{
if (_notification == null)
return;
_notification.Quantity = value;
OnPropertyChanged( () => Quantity );
}
}
public int Maximum => _notification?.Maximum ?? 0;
#region IInteractionRequestAware
public INotification Notification
{
get { return _notification; }
set
{
SetProperty( ref _notification, value as SelectQuantityNotification );
OnPropertyChanged( () => Maximum );
OnPropertyChanged( () => Quantity );
}
}
public Action FinishInteraction
{
get;
set;
}
#endregion
#region private
private SelectQuantityNotification _notification;
private void OnOk()
{
if (_notification != null)
_notification.Confirmed = true;
FinishInteraction();
}
#endregion
}
我使用 Prism Unity、WPF 和 Mvvm 在应用程序中创建了自定义确认 window。我需要有关需要发送回视图模型的通知的帮助。我在详细记录视图中有这个,我们称它为 MyDetailView。
<!-- Custom Confirmation Window -->
<ie:Interaction.Triggers>
<interactionRequest:InteractionRequestTrigger
SourceObject="{Binding ConfirmationRequest, Mode=TwoWay}">
<mycontrols:PopupWindowAction1 IsModal="True"/>
</interactionRequest:InteractionRequestTrigger>
</ie:Interaction.Triggers>
如上所示,我设置了交互 Mode=TwoWay,以便确认弹出窗口 window 可以发回“确定”或“取消”按钮的按钮点击结果。确认 window 按原样出现,但我不知道如何将按钮点击结果发送回我的视图模型,比如 MyDetailViewModel。这是主要问题。
编辑:这是引发 InteractionRequest 的 MyDetailViewMmodel 方法。
private void RaiseConfirmation()
{ConfirmationRequest
.Raise(new Confirmation()
{
Title = "Confirmation Popup",
Content = "Save Changes?"
}, c =>{if (c.Confirmed)
{ UoW.AdrTypeRos.Submit();}
这是 PopupWindowAction1 class。该问题的部分答案可能是我如何实现 Notification 和 FinishedInteraction 方法。
class PopupWindowAction1 : PopupWindowAction, IInteractionRequestAware
{
protected override Window GetWindow(INotification notification)
{ // custom metrowindow using mahapps
MetroWindow wrapperWindow = new ConfirmWindow1();
wrapperWindow.DataContext = notification;
wrapperWindow.Title = notification.Title;
this.PrepareContentForWindow(notification, wrapperWindow);
return wrapperWindow;
}
public INotification Notification
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public Action FinishInteraction
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
是否需要在我的 ConfirmWindow1 中加入一些互动,比如这样的?
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<ei:CallMethodAction
TargetObject="{Binding RelativeSource={RelativeSource AncestorType=UserControl},
Path=DataContext}"
MethodName="DataContext.ValidateConfirm"/>
</i:EventTrigger>
</i:Interaction.Triggers>
我什至需要在按钮中进行这种类型的交互吗?如果是这样,我如何编写它需要的代码,以便它对应于调用交互的特定视图模型。有什么建议么?谢谢。
最主要的是,当你引发交互时,提供一个回调,当交互完成时触发。此回调会返回通知,您的交互应该已将所有可能有趣的 return 值存储在那里。
这是一个例子...
ViewModel 的相关部分:
public InteractionRequest<SelectQuantityNotification> SelectQuantityRequest
{
get;
}
// in some handler that triggers the interaction
SelectQuantityRequest.Raise( new SelectQuantityNotification { Title = "Load how much stuff?", Maximum = maximumQuantity },
notification =>
{
if (notification.Confirmed)
_worldStateService.ExecuteCommand( new LoadCargoCommand( sourceStockpile.Stockpile, cartViewModel.Cart, notification.Quantity ) );
} );
...从视图中:
<i:Interaction.Triggers>
<interactionRequest:InteractionRequestTrigger
SourceObject="{Binding SelectQuantityRequest, Mode=OneWay}">
<framework:FixedSizePopupWindowAction>
<interactionRequest:PopupWindowAction.WindowContent>
<views:SelectSampleDataForImportPopup/>
</interactionRequest:PopupWindowAction.WindowContent>
</framework:FixedSizePopupWindowAction>
</interactionRequest:InteractionRequestTrigger>
</i:Interaction.Triggers>
此外,我们需要一个 class 来保存传递的数据,以及一个 ViewModel/View 对用于交互本身。
这是持有 class 的数据(注意 Maximum
被传递 到 交互,并且 Quantity
returned 来自它):
internal class SelectQuantityNotification : Confirmation
{
public int Maximum
{
get;
set;
}
public int Quantity
{
get;
set;
}
}
这是交互弹窗的视图:
<UserControl x:Class="ClientModule.Views.SelectSampleDataForImportPopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Vertical">
<TextBlock>
Amount: <Run Text="{Binding Quantity}"/>
</TextBlock>
<Slider Orientation="Horizontal" Minimum="0" Maximum="{Binding Maximum}" Value="{Binding Quantity}" TickPlacement="BottomRight"/>
<Button Content="Ok" Command="{Binding OkCommand}"/>
</StackPanel>
</UserControl>
它是 ViewModel:
internal class SelectSampleDataForImportPopupViewModel : BindableBase, IInteractionRequestAware
{
public SelectSampleDataForImportPopupViewModel()
{
OkCommand = new DelegateCommand( OnOk );
}
public DelegateCommand OkCommand
{
get;
}
public int Quantity
{
get { return _notification?.Quantity ?? 0; }
set
{
if (_notification == null)
return;
_notification.Quantity = value;
OnPropertyChanged( () => Quantity );
}
}
public int Maximum => _notification?.Maximum ?? 0;
#region IInteractionRequestAware
public INotification Notification
{
get { return _notification; }
set
{
SetProperty( ref _notification, value as SelectQuantityNotification );
OnPropertyChanged( () => Maximum );
OnPropertyChanged( () => Quantity );
}
}
public Action FinishInteraction
{
get;
set;
}
#endregion
#region private
private SelectQuantityNotification _notification;
private void OnOk()
{
if (_notification != null)
_notification.Confirmed = true;
FinishInteraction();
}
#endregion
}