07Prism WPF 入門實戰 - Dialog


概要

Prism中的dialog(對話框)實際上是我們應用程序經常用到得一個功能,類如:Show、Show Dialog。可以彈出一個我們指定得窗口,僅此而已那么在Prism當中,Dialog指的什么?Prism提供了一組對話服務,封裝了常用的對話框組件的功能,例如:IDialogAware(注冊對話及使用對話)打開對話框傳遞參數/關閉對話框返回參數回調通知對話結果。

 

  • 應用場景:處理一些公共業務,例如正在編輯文章內容這時候如果要關閉程序或者打開其他頁面需要提示。
  • 在Prism體系中的應用分為,1.自定義dialog窗體 2.將寫好的dialog注入到App.xaml.csI中的ContainerRegistry里。3.業務ViewModel的構造函數中獲取引用進行調用

 

詳細內容

 

我們先來看看它源碼中的定義:

namespace Prism.Services.Dialogs { //  // 摘要:  // Interface that provides dialog functions and events to ViewModels.  public interface IDialogAware { //  // 摘要:  // The title of the dialog that will show in the window title bar.  string Title { get; } //  // 摘要:  // Instructs the Prism.Services.Dialogs.IDialogWindow to close the dialog.  event Action<IDialogResult> RequestClose; //  // 摘要:  // Determines if the dialog can be closed.  //  // 返回結果:  // If true the dialog can be closed. If false the dialog will not close.  bool CanCloseDialog(); //  // 摘要:  // Called when the dialog is closed.  void OnDialogClosed(); //  // 摘要:  // Called when the dialog is opened.  //  // 參數:  // parameters:  // The parameters passed to the dialog.  void OnDialogOpened(IDialogParameters parameters); } } 

 

解讀一下IDialogAware接口中內容各有什么作用。

  • (1)string Title{get;} //將顯示在窗口標題欄中的對話框的標題。
  • (2)event Action<IDialogResult> RequestClose;//指示 Prism.Services.Dialogs.IDialogWindow 關閉對話框。
  • (3)bool CanCloseDialog();//確定是否可以關閉對話框。
  • (4)void OnDialogClosed();//關閉對話框時觸發
  • (5)void OnDialogOpened(IDialogParameters parameters);//打開對話框時觸發, parameters:傳遞給對話框的參數。

 

應用

首先創建好Dialog的窗體的.xaml和窗體處理邏輯的.cs文件,盡量創建在“公共庫”里。

 

 

.Xaml文件內容

<UserControl x:Class="Wemail.Controls.Views.MessageDialogView"
            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"
            TextElement.Foreground="{DynamicResource MaterialDesignBody}"
            Background="{DynamicResource MaterialDesignPaper}"
            xmlns:local="clr-namespace:Wemail.Controls.Views"
            mc:Ignorable="d"
            Height="450" Width="500">
   <Grid>
       <Grid.RowDefinitions>
           <RowDefinition Height="40"></RowDefinition>
           <RowDefinition Height="*"></RowDefinition>
           <RowDefinition Height="40"></RowDefinition>
       </Grid.RowDefinitions>
       <TextBox Grid.Row="1" Background="Transparent" Foreground="White" Text="{Binding MessageContent,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
       <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
           <Button Width="100" Height="30" Margin="5" Content="確定" Command="{Binding GetMessageCommand}"></Button>
           <Button Width="100" Height="30" Margin="5" Content="取消" Command="{Binding CancelMessageCommand}"></Button>
       </StackPanel>
   </Grid>
</UserControl>

.cs文件內容

namespace Wemail.Controls.CustomContorls
{
  public class MessageDialogControl : BindableBase , IDialogAware
  {
      private DelegateCommand _getMessageCommand;
      private DelegateCommand _cancelMessageCommand;
      private string _messageContent;

      public string MessageContent
      {
          get => _messageContent;
          set
          {
              _messageContent = value;
              SetProperty(ref _messageContent, value);
          }
      }

      /// <summary>
      /// 確定按鈕
      /// </summary>
      public DelegateCommand GetMessageCommand
      {
          get => _getMessageCommand = new DelegateCommand(() =>
          {
              var parameter = new DialogParameters();
              parameter.Add("MessageContent", MessageContent);
              RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameter));
          });
      }

      /// <summary>
      /// 窗體關閉按鈕
      /// </summary>
      public DelegateCommand CancelMessageCommand
      {
          get => _cancelMessageCommand = new DelegateCommand(() =>
          {
              RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
          });
      }

      public string Title => "Message";
      public event Action<IDialogResult> RequestClose;

      /// <summary>
      /// 允許用戶手動關閉當前窗口
      /// </summary>
      /// <returns></returns>
      public bool CanCloseDialog()
      {
          //根據業務需要來控制是否允許手動關閉
          return true;
      }

      /// <summary>
      /// 關閉dialog的操作
      /// </summary>
      /// <exception cref="NotImplementedException"></exception>
      public void OnDialogClosed()
      {
          //當關閉dialog的時候會觸發的回調,一般用來打日志或者用於用戶行為記錄等場景
      }

      /// <summary>
      /// dialog接收參數傳遞
      /// </summary>
      /// <param name="parameters"></param>
      /// <exception cref="NotImplementedException"></exception>
      public void OnDialogOpened(IDialogParameters parameters)
      {
          //接受viewmodel打開dialog時傳遞的參數內容
          var parameterContent = parameters.GetValue<string>("juster");
      }
  }
}

注冊dialog

App.xaml.cs文件使用如下:

  protected override void RegisterTypes(IContainerRegistry containerRegistry)
  {
      var factory = new NLog.Extensions.Logging.NLogLoggerFactory();
      _logger = factory.CreateLogger("NLog");
      //注入到Prism DI容器中
      containerRegistry.RegisterInstance(_logger);

      //注冊Dialog窗體
      containerRegistry.RegisterDialog<MessageDialogView, MessageDialogControl>();
  }

 

ViewModel中使用

namespace Wemail.ViewModels
{
  public class MainWindowViewModel : BindableBase
  {
      private string _title = "Prism Application";

      //Region管理對象
      private IRegionManager _regionManager;
      private IModuleCatalog _moduleCatalog;
      private IModuleInfo _moduleInfo;
      private ILogger _logger;
      private IDialogService _dialogService;
      private ObservableCollection<IModuleInfo> _modules;
      private DelegateCommand _loadModulesCommand;
      private DelegateCommand _showDialogCommand;
       
      public IView View { get; set; }

      public string Title
      {
          get { return _title; }
          set { SetProperty(ref _title, value); }
      }

      public ObservableCollection<IModuleInfo> Modules
      {
          get => _modules ?? (_modules = new ObservableCollection<IModuleInfo>());
      }

      public DelegateCommand LoadModulesCommand { get => _loadModulesCommand = new DelegateCommand(InitModules); }

      public IModuleInfo ModuleInfo
      {
          get
          {
              return _moduleInfo;
          }

          set
          {
              _moduleInfo = value;
              Navigate(value);
          }
      }

      public DelegateCommand ShowDialogCommand { get => _showDialogCommand = new DelegateCommand(ShowDialogAction); }

      /// <summary>
      /// 調用dialog
      /// </summary>
      private void ShowDialogAction()
      {
          //需要傳遞給對話框處理的內容參數
          DialogParameters dialogParameters = new DialogParameters();
          dialogParameters.Add("juster","nihao");
          //打開dialog的時候傳遞
          _dialogService.ShowDialog("MessageDialogView", dialogParameters, (r) =>
          {
              var result = r.Result;
              if (result == ButtonResult.OK)
              {
                  var parameter = r.Parameters.GetValue<string>("MessageContent");
              }
          });
      }

      public MainWindowViewModel(IRegionManager regionManager, IModuleCatalog moduleCatalog,ILogger logger,IDialogService dialogService)
      {
          _dialogService = dialogService;
          _logger = logger;
          _regionManager = regionManager;
          _moduleCatalog = moduleCatalog;
      }

      public void InitModules()
      {
          var dirModuleCatalog = _moduleCatalog as DirectoryModuleCatalog;
          Modules.AddRange(dirModuleCatalog.Modules);
      }

      private void Navigate(IModuleInfo info)
      {
          var paramete = new NavigationParameters();
          //任意定義key,value。導航到的視圖按照約定key獲取value即可。
          paramete.Add($"{ info.ModuleName }", DateTime.Now.ToString());
          _regionManager.RequestNavigate("ContentRegion", $"{ info.ModuleName }View", paramete);
      }
  }
}

運行效果

 

 

關閉對話框之后viewmodel接收到的參數

 

 

窗體被打開時接收到viewmodel的參數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM