2016-02-06 55 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