顯示具有 Prism 標籤的文章。 顯示所有文章
顯示具有 Prism 標籤的文章。 顯示所有文章
InteractionRequest

InteractionRequest

Interaction Request

View 端繫結 ViewModel 端所公布Interaction Request object。 當ViewModel端有需要時,用該Interaction Request object的 Raise函數發出請求,由View端加以處理。

NotificationRequest

ViewModel

public class MyViewModel : BindableBase
{
  public InteractionRequest<INotification> NotificationRequest { get; private set; }
 
  public MyViewModel(){
    ...
    this.NotificationRequest = new InteractionRequest<INotification>();
    ...
  }
  private void DoSomething(){
    ...
    this.NotificationRequest.Raise(
      new Notification { Content = "Notification Message", Title = "Notification" },
        n => { });
    ...
  }
}

View

<UserControl
...
  xmlns:prism="http://prismlibrary.com/"
  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
  ...
>
<i:Interaction.Triggers>
  <prism:InteractionRequestTrigger SourceObject="{Binding NotificationRequest, Mode=OneWay}">
    <!-- This PopupWindowAction does not have a custom view defined, therefore it will try to use a DefaultConfirmationWindow -->
    <!-- which is a window used by default by Prism to shown IConfirmation implementations -->
    <!-- That window will be show as a modal dialog and centered over this window -->
    <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"/>
  </prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
...
</UserControl>

ConfirmationRequest

ViewModel

public class MyViewModel : BindableBase
{
  public InteractionRequest<IConfirmation> ConfirmationRequest { get; private set; }
  public MyViewModel(){
    ...
    this.ConfirmationRequest = new InteractionRequest<IConfirmation>();
    ...
  }
  private void DoSomething(){
    ...
    bool isConfirmed = false;
    this.ConfirmationRequest.Raise(
      new Confirmation {
        Content = "Do you really want to delete PItem " + CurPItem.Name + "?",
        Title = "Confirmation" },
      c => { isConfirmed = c.Confirmed; });
    if (isConfirmed)
    ...
  }
}

View

<UserControl
...
  xmlns:prism="http://prismlibrary.com/"
  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
  ...
>
<i:Interaction.Triggers>
  <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest, Mode=OneWay}">
    <!-- This PopupWindowAction does not have a custom view defined, therefore it will try to use a DefaultNotificationWindow -->
    <!-- which is a window used by default by Prism to shown INotification implementations -->
    <!-- That window will be show as a modal dialog and centered over this window -->
    <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"/>
  </prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
...
</UserControl>
SelectionChangedSelectedItemsTutorial

SelectionChangedSelectedItemsTutorial

InvokeCommandAction

介紹 InvokeCommandAction

Prism 的 InvokeCommandAction 比 Blend 的 InvokeCommandAction 功能強大。

Advanced MVVM Scenarios Using the Prism Library for WPF 提到:

Prism’s InvokeCommandAction differs from the class of the same name in the Blend SDK in two ways.

First, the Prism InvokeCommandAction updates the enabled state of the associated control based on the return value of the command’s CanExecute method.

Second, the Prism InvokeCommandAction uses the EventArgs parameter passed to it from the parent trigger, passing it to the associated command if the CommandParameter is not set.

Prism’s InvokeCommandAction has a property called TriggerParameterPath that is used to specify the member property of the EventArgs passed as the command parameter.

練習

View的部分

<UserControl x:Class="ModuleSelectionChange.Views.ViewA"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:prism="http://prismlibrary.com/"             
 prism:ViewModelLocator.AutoWireViewModel="True"
 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
 >
<Grid>
...
<ListBox ItemsSource="{Binding Names}" SelectionMode="Extended" >
 <i:Interaction.Triggers>
  <!-- This event trigger will execute the action when the corresponding event is raised by the ListBox. -->
  <i:EventTrigger EventName="SelectionChanged">
      <!-- This action will invoke the selected command in the view model and pass the parameters of the event to it. -->
      <prism:InvokeCommandAction Command="{Binding AddedCommand}" TriggerParameterPath="AddedItems" />
  </i:EventTrigger>
  <i:EventTrigger EventName="SelectionChanged">
      <prism:InvokeCommandAction Command="{Binding RemovedCommand}" TriggerParameterPath="RemovedItems" />
  </i:EventTrigger>
  <i:EventTrigger EventName="SelectionChanged">
      <prism:InvokeCommandAction Command="{Binding SelectedItemsCommand}" TriggerParameterPath="Source.SelectedItems" />
  </i:EventTrigger>
  <i:EventTrigger EventName="SelectionChanged">
      <prism:InvokeCommandAction Command="{Binding SelectedCommand}" TriggerParameterPath="Source" />
  </i:EventTrigger>
  <i:EventTrigger EventName="SelectionChanged">
      <prism:InvokeCommandAction Command="{Binding EventArgsCommand}"  />
  </i:EventTrigger>
 </i:Interaction.Triggers>
</ListBox>
...
</Grid>

ViewModel 的部分

public class ViewAViewModel : BindableBase
{
    public ObservableCollection<string> Names { get; private set; }
    private string _Added;
    public string Added
    {
        get { return _Added; }
        set { SetProperty(ref _Added, value); }
    }
    private string _Removed;
    public string Removed
    {
        get { return _Removed; }
        set { SetProperty(ref _Removed, value); }
    }
    private string _Selected;
    public string Selected
    {
        get { return _Selected; }
        set { SetProperty(ref _Selected, value); }
    }
    private string _SelectedItems;
    public string SelectedItems
    {
        get { return _SelectedItems; }
        set { SetProperty(ref _SelectedItems, value); }
    }
    private string _EventArgs;
    public string EventArgs
    {
        get { return _EventArgs; }
        set { SetProperty(ref _EventArgs, value); }
    }
    public DelegateCommand<object> SelectedCommand { get; private set; }
    public DelegateCommand<object[]> AddedCommand { get; private set; }
    public DelegateCommand<object[]> RemovedCommand { get; private set; }
    public DelegateCommand<System.Collections.ICollection> SelectedItemsCommand { get; private set; }
    public DelegateCommand<System.Windows.Controls.SelectionChangedEventArgs> EventArgsCommand { get; private set; } 
    private void GetAddedItem(object[] listOfItems)
    {
        string res = GetList(listOfItems);
        Added = res;
    }
    private void GetRemovedItem(object[] listOfItems)
    {
        string res = GetList(listOfItems);
        Removed = res;
    }
    private void GetSelectedItems2(System.Collections.ICollection listOfItems)
    {
        string res = "";
        foreach(var x in listOfItems)
            res += x + "\n";
        SelectedItems = res;
    }
    private void GetEventArgs(System.Windows.Controls.SelectionChangedEventArgs args)
    {
        string res = "Added:\n";
        for (int i = 0; i < args.AddedItems.Count; i++)
            res += args.AddedItems[i]+"\n";
        res += "Removed:\r\n";
        for (int i = 0; i < args.RemovedItems.Count; i++)
            res += args.RemovedItems[i]+"\n";
        res += "Selected:\n";
        var items = (args.Source as System.Windows.Controls.ListBox).SelectedItems;
        for (int i = 0; i < items.Count; i++)
            res += items[i] + "\n";
        EventArgs = res;
    }
    private static string GetList(object[] listOfItems)
    {
        string res = "";
        if (listOfItems != null && listOfItems.Count() > 0)
        {
            for (int i = 0; i < listOfItems.Count(); i++)
                res = res + listOfItems[i].ToString() + "\r\n";
        }
        return res;
    }
    private void GetSelectedItems(object source)
    {
        var listOfItems = (source as System.Windows.Controls.ListBox).SelectedItems;
        string res = "";
        if (listOfItems != null && listOfItems.Count > 0)
        {
            for (int i = 0; i < listOfItems.Count; i++)
                res = res + listOfItems[i].ToString() + "\r\n";
        }
        Selected = res;
    }
    public ViewAViewModel()
    {
        Names = new ObservableCollection<string>() {"Yang","Hon","Jang"};
        this.AddedCommand = new DelegateCommand<object[]>(GetAddedItem);
        this.RemovedCommand = new DelegateCommand<object[]>(GetRemovedItem);
        this.SelectedCommand = new DelegateCommand<object>(GetSelectedItems);
        this.SelectedItemsCommand = new DelegateCommand<System.Collections.ICollection>(GetSelectedItems2);
        this.EventArgsCommand = new DelegateCommand<System.Windows.Controls.SelectionChangedEventArgs>(GetEventArgs);
    }
}

說明

ListBox 發生SelectionChanged事件的時候,EventArgs裡的屬性有AddedItems,RemovedItems,Source。其中,Source是ListBox本身。

下面我們利用各種屬性透過 TriggerParameterPath 傳遞給Command當參數。

AddedItems

<prism:InvokeCommandAction Command="{Binding AddedCommand}" TriggerParameterPath="AddedItems" />

AddedCommand的格式為

public DelegateCommand<object[]> AddedCommand { get; private set; }

RemovedItems

<prism:InvokeCommandAction Command="{Binding RemovedCommand}" TriggerParameterPath="RemovedItems" />

RemovedCommand的格式為

public DelegateCommand<object[]> RemovedCommand { get; private set; }

Source

<prism:InvokeCommandAction Command="{Binding SelectedCommand}" TriggerParameterPath="Source" />

SelectedCommand的格式為

public DelegateCommand<object> SelectedCommand { get; private set; }

Source.SelectedItems

<prism:InvokeCommandAction Command="{Binding SelectedItemsCommand}" TriggerParameterPath="Source.SelectedItems" />

SelectedItemsCommand的格式為

public DelegateCommand<System.Collections.ICollection> SelectedItemsCommand { get; private set; }

EventArgs

<prism:InvokeCommandAction Command="{Binding EventArgsCommand}"  />

EventArgsCommand 的格式為

public DelegateCommand<System.Windows.Controls.SelectionChangedEventArgs> EventArgsCommand { get; private set; } 
技術提供:Blogger.