2016-02-06 8 views
2

我在Prism Unity,WPF & Mvvm的应用程序中创建了自定义确认窗口。我需要帮助才能将需要发送回视图模型的通知。我在详细记录视图中有这个,我们称之为MyDetailView。棱镜定制确认互动

<!-- Custom Confirmation Window --> 
<ie:Interaction.Triggers> 
    <interactionRequest:InteractionRequestTrigger 
     SourceObject="{Binding ConfirmationRequest, Mode=TwoWay}"> 
    <mycontrols:PopupWindowAction1 IsModal="True"/> 
    </interactionRequest:InteractionRequestTrigger> 
</ie:Interaction.Triggers> 

如上图所示,我所做的交互模式=双向,以便确认弹出窗口中可以发送回按钮点击结果的确定或取消按钮。确认窗口应该显示,但我不知道如何将按钮点击结果发送回我的viewmodel,比如MyDetailViewModel。这是主要问题。

编辑:这是引发InteractionRequest的MyDetailViewMmodel方法。

private void RaiseConfirmation() 
{ConfirmationRequest 
    .Raise(new Confirmation() 
    { 
     Title = "Confirmation Popup", 
     Content = "Save Changes?" 
    }, c =>{if (c.Confirmed) 
{ UoW.AdrTypeRos.Submit();} 

这是PopupWindowAction1类。部分问题的答案可能是如何实现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> 

我是否甚至需要在按钮中进行这种类型的交互?如果是这样,我该如何编码它,以便它对应于调用交互的特定视图模型。有什么建议么?谢谢。

回答

5

主要的是,当你提出交互时,提供一个回调,当交互完成时触发。这个回调获取通知,你的交互应该已经存储了所有可能有趣的返回值。

下面是一个例子...

视图模型的相关部分:

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> 

此外,我们还需要一个类来保存传递的数据以及交互本身的ViewModel/View对。

这里的数据保持类(注意,Maximum传递的相互作用,Quantity从它返回):

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 
} 
+0

谢谢。我会试试看。 – harpagornis

+0

我有一个不同的是,我试图在双向模式中进行交互请求。另一个是我使用MetroWindow作为确认弹出窗口,即。 wrapperWindow。DataContext =通知;这将我的弹出窗口的DataContext设置为InteractionRequest,因此为了修改我的代码以匹配建议,我需要以某种方式更新弹出窗口的viewmodel中的Notification属性,当它接管新的DataContext时。 – harpagornis

+0

双向或单向只影响绑定,我使用OneWay,因为我的'SelectQuantityRequest'属性是只读的,不需要改变。 Notification-Property来自实现'IInteractionRequestAware',它应该由框架来设置。 – Haukinger