NET Framework Core 3 WPF MVVM serie Prisma de gerente regional

En este artículo se describe cómo utilizar el marco de Prisma MVVM en entornos .NET Core3 para la visión regional Manager,

Un gerente regional

Antes se construyó una serie de proyectos de tipo estándar Prisma, antes de que este artículo se explicará el uso del área utilizada en el gestor de proyectos para gestionar mejor nuestra opinión, vamos a ver el mismo oficial dada diagrama de modelo:

Ahora que podemos saber es que aproximadamente la región del punto de gestor región RegionMannager crear un control:

  • Creación Región de control debe contener un adaptador RegionAdapter
  • región depende de tener organismo de control RegionAdapter

De hecho, más tarde me fui en la descripción y el código fuente oficial, hay tres RegionAdapter por defecto, y también es compatible con RegionAdapter costumbre, y por lo tanto entre el diagrama del modelo oficial que hizo un punto de añadir:

II. Implantado región para crear y ver

Vamos a echar un vistazo a la región dividida de nuestros proyectos anteriores, y cómo crear el área de la vista y se inyecta en la zona:

Ponemos todo el formulario principal se divide en cuatro áreas:

  • ShowSearchPatientRegion : inyectado vista ShowSearchPatient
  • PatientListRegion : inyectado vista PatientList
  • FlyoutRegion : inyectado vista PatientDetail y SearchMedicine
  • ShowSearchPatientRegion : inyectado vista ShowSearchPatient

En Prisma, nos damos cuenta de que hay dos maneras de crear y ver la zona de inyección:

  1. ViewDiscovery
  2. ViewInjection

1. ViewDiscovery

Nos intercepción, que PatientListRegion código para crear y ver inyectado (más cuidadoso puede ir a ver el código fuente de demostración):

MainWindow.xaml:

<ContentControl Grid.Row="2" prism:RegionManager.RegionName="PatientListRegion" Margin="10"/>

Aquí el equivalente en los MainWindow.cs fondo:

RegionManager.SetRegionName(ContentControl, "PatientListRegion");

PatientModule.cs:

 public class PatientModule : IModule
 {
    public void OnInitialized(IContainerProvider containerProvider)
    {
         var regionManager = containerProvider.Resolve<IRegionManager>();
         //PatientList
         regionManager.RegisterViewWithRegion(RegionNames.PatientListRegion, typeof(PatientList));
         //PatientDetail-Flyout
         regionManager.RegisterViewWithRegion(RegionNames.FlyoutRegion, typeof(PatientDetail));
           
     }

    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
           
    }
 }

2. ViewInjection

Utilizamos caso MainWindow cargado de la forma ViewInjection manera de inyectar vista PatientList

MainWindow.xaml:

  <i:Interaction.Triggers>
      <i:EventTrigger EventName="Loaded">
          <i:InvokeCommandAction Command="{Binding LoadingCommand}"/>
       /i:EventTrigger>
  </i:Interaction.Triggers>

MainWindowViewModel.cs:

      
private IRegionManager _regionManager;
private IRegion _paientListRegion;        
private PatientList _patientListView;

private DelegateCommand _loadingCommand;
public DelegateCommand LoadingCommand =>
     _loadingCommand ?? (_loadingCommand = new DelegateCommand(ExecuteLoadingCommand));

void ExecuteLoadingCommand()
{
     _regionManager = CommonServiceLocator.ServiceLocator.Current.GetInstance<IRegionManager>();
     _paientListRegion = _regionManager.Regions[RegionNames.PatientListRegion];
     _patientListView = CommonServiceLocator.ServiceLocator.Current.GetInstance<PatientList>();
     _paientListRegion.Add(_patientListView);

 }
      

Podemos sentir claramente dos maneras diferentes, ViewDiscovery manera materializó vista se carga automáticamente y por fuera, y ViewInjection manera es para ver el tiempo de inyección puede ser controlada manualmente y vista cargado (evento cargado por el ejemplo anterior), para el funcionario tanto escenario recomendado es el siguiente:

ViewDiscovery :

  • Ver cargado automáticamente según sea necesario o deseado
  • instancia individual se cargará en la región vista

ViewInjection :

  • Se requiere programación o control cuando para crear y display explícita, o tiene que quitar la vista de la zona de
  • Es necesario para mostrar varias instancias de la misma vista en la región, donde cada vista es diferentes instancias de la unión a los datos
  • Qué instancia debe ser controlada para añadir el área de la vista
  • Las aplicaciones que utilizan la API de navegación (se mencionará más adelante)

III. El fracaso para activar con una vista

Activar Desactivar 和

En primer lugar, tenemos que controlar la activación de PatientList y MedicineMainContent dos puntos de vista sobre el código:

MainWindow.xaml:

<StackPanel Grid.Row="1">
    <Button  Content="Load MedicineModule" FontSize="25"  Margin="5" Command="{Binding LoadMedicineModuleCommand}"/>
     <UniformGrid Margin="5">
         <Button Content="ActivePaientList" Margin="5" Command="{Binding ActivePaientListCommand}"/>
         <Button Content="DeactivePaientList" Margin="5" Command="{Binding DeactivePaientListCommand}"/>
         <Button Content="ActiveMedicineList" Margin="5" Command="{Binding ActiveMedicineListCommand}"/>
         <Button Content="DeactiveMedicineList" Margin="5" Command="{Binding DeactiveMedicineListCommand}"/>
     </UniformGrid>
</StackPanel>

<ContentControl Grid.Row="2" prism:RegionManager.RegionName="PatientListRegion" Margin="10"/>
<ContentControl Grid.Row="3" prism:RegionManager.RegionName="MedicineMainContentRegion"/>

MainWindowViewModel.cs:

  private IRegionManager _regionManager;
  private IRegion _paientListRegion;
  private IRegion _medicineListRegion;
  private PatientList _patientListView;
  private MedicineMainContent _medicineMainContentView;

  private bool _isCanExcute = false;
  public bool IsCanExcute
  {
     get { return _isCanExcute; }
     set { SetProperty(ref _isCanExcute, value); }
  }

  private DelegateCommand _loadingCommand;
  public DelegateCommand LoadingCommand =>
      _loadingCommand ?? (_loadingCommand = new DelegateCommand(ExecuteLoadingCommand));

  private DelegateCommand _activePaientListCommand;
  public DelegateCommand ActivePaientListCommand =>
      _activePaientListCommand ?? (_activePaientListCommand = new DelegateCommand(ExecuteActivePaientListCommand));

  private DelegateCommand _deactivePaientListCommand;
  public DelegateCommand DeactivePaientListCommand =>
      _deactivePaientListCommand ?? (_deactivePaientListCommand = new DelegateCommand(ExecuteDeactivePaientListCommand));

   private DelegateCommand _activeMedicineListCommand;
   public DelegateCommand ActiveMedicineListCommand =>
      _activeMedicineListCommand ?? (_activeMedicineListCommand = new DelegateCommand(ExecuteActiveMedicineListCommand).ObservesCanExecute(() => IsCanExcute));

   private DelegateCommand _deactiveMedicineListCommand;
   public DelegateCommand DeactiveMedicineListCommand =>
       _deactiveMedicineListCommand ?? (_deactiveMedicineListCommand = new DelegateCommand(ExecuteDeactiveMedicineListCommand).ObservesCanExecute(() => IsCanExcute));

   private DelegateCommand _loadMedicineModuleCommand;
   public DelegateCommand LoadMedicineModuleCommand =>
       _loadMedicineModuleCommand ?? (_loadMedicineModuleCommand = new DelegateCommand(ExecuteLoadMedicineModuleCommand));

 /// <summary>
 /// 窗体加载事件
 /// </summary>
 void ExecuteLoadingCommand()
 {
      _regionManager = CommonServiceLocator.ServiceLocator.Current.GetInstance<IRegionManager>();
      _paientListRegion = _regionManager.Regions[RegionNames.PatientListRegion];
      _patientListView = CommonServiceLocator.ServiceLocator.Current.GetInstance<PatientList>();
      _paientListRegion.Add(_patientListView);
      _medicineListRegion = _regionManager.Regions[RegionNames.MedicineMainContentRegion];
 }

  /// <summary>
  /// 失效medicineMainContent视图
  /// </summary>
  void ExecuteDeactiveMedicineListCommand()
  {
      _medicineListRegion.Deactivate(_medicineMainContentView);
  }

  /// <summary>
  /// 激活medicineMainContent视图
  /// </summary>
  void ExecuteActiveMedicineListCommand()
  {
      _medicineListRegion.Activate(_medicineMainContentView);
  }

  /// <summary>
  /// 失效patientList视图
  /// </summary>
  void ExecuteDeactivePaientListCommand()
  {
       _paientListRegion.Deactivate(_patientListView);
  }

  /// <summary>
  /// 激活patientList视图
  /// </summary>
  void ExecuteActivePaientListCommand()
  {
       _paientListRegion.Activate(_patientListView);
  }
  
  /// <summary>
  /// 加载MedicineModule
  /// </summary>
  void ExecuteLoadMedicineModuleCommand()
  {
       _moduleManager.LoadModule("MedicineModule");
       _medicineMainContentView = (MedicineMainContent)_medicineListRegion.Views.Where(t => t.GetType() == typeof(MedicineMainContent)).FirstOrDefault();
       this.IsCanExcute = true;
   }

Los resultados son los siguientes:

estado de activación monitor de vista

Prism que también es compatible con el estado de activación vista de supervisión, se logra a través de la herencia IActiveAware en View, tenemos para activar el estado de vigilancia en el que vista MedicineMainContent como un ejemplo:

MedicineMainContentViewModel.cs:

 public class MedicineMainContentViewModel : BindableBase,IActiveAware
 {
     public event EventHandler IsActiveChanged;

     bool _isActive;
     public bool IsActive
     {
         get { return _isActive; }
         set
         {
             _isActive = value;
             if (_isActive)
             {
                 MessageBox.Show("视图被激活了");
             }
             else
             {
                 MessageBox.Show("视图失效了");
             }
             IsActiveChanged?.Invoke(this, new EventArgs());
          }
      }

  }

Agregar y quitar

El ejemplo anterior con la ContentControl, que a continuación, un ejemplo ItemsControl, como sigue:

MainWindow.xaml:

  <metro:MetroWindow.RightWindowCommands>
      <metro:WindowCommands x:Name="rightWindowCommandsRegion" />
  </metro:MetroWindow.RightWindowCommands>

MainWindow.cs:

 public MainWindow()
 {
    InitializeComponent();
    var regionManager= ServiceLocator.Current.GetInstance<IRegionManager>();
    if (regionManager != null)
    {
       SetRegionManager(regionManager, this.flyoutsControlRegion, RegionNames.FlyoutRegion);
       SetRegionManager(regionManager, this.rightWindowCommandsRegion, RegionNames.ShowSearchPatientRegion);//创建WindowCommands控件区域
    }
 }

 void SetRegionManager(IRegionManager regionManager, DependencyObject regionTarget, string regionName)
 {
     RegionManager.SetRegionName(regionTarget, regionName);
     RegionManager.SetRegionManager(regionTarget, regionManager);
 }

ShowSearchPatient.xaml:

<StackPanel x:Class="PrismMetroSample.MedicineModule.Views.ShowSearchPatient"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:prism="http://prismlibrary.com/"  
           xmlns:const="clr-namespace:PrismMetroSample.Infrastructure.Constants;assembly=PrismMetroSample.Infrastructure"
           Orientation="Horizontal"    
           xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            prism:ViewModelLocator.AutoWireViewModel="True">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding ShowSearchLoadingCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <CheckBox IsChecked="{Binding IsShow}"/>
    <Button Command="{Binding ApplicationCommands.ShowCommand}" CommandParameter="{x:Static const:FlyoutNames.SearchMedicineFlyout}">
        <StackPanel Orientation="Horizontal">
            <Image Height="20" Source="pack://application:,,,/PrismMetroSample.Infrastructure;Component/Assets/Photos/按钮.png"/>
            <TextBlock Text="Show" FontWeight="Bold" FontSize="15" VerticalAlignment="Center"/>
        </StackPanel>
    </Button>
</StackPanel>

ShowSearchPatientViewModel.cs:

 private IApplicationCommands _applicationCommands;
 private readonly IRegionManager _regionManager;
 private ShowSearchPatient _showSearchPatientView;
 private IRegion _region;

 public IApplicationCommands ApplicationCommands
 {
      get { return _applicationCommands; }
      set { SetProperty(ref _applicationCommands, value); }
 }

 private bool _isShow=true;
 public bool IsShow
 {
      get { return _isShow=true; }
      set 
      { 
          SetProperty(ref _isShow, value);
          if (_isShow)
          {
               ActiveShowSearchPatient();
          }
          else
          {
               DeactiveShowSearchPaitent();
          }
      }
 }

 private DelegateCommand _showSearchLoadingCommand;
 public DelegateCommand ShowSearchLoadingCommand =>
         _showSearchLoadingCommand ?? (_showSearchLoadingCommand = new DelegateCommand(ExecuteShowSearchLoadingCommand));

 void ExecuteShowSearchLoadingCommand()
 {
        _region = _regionManager.Regions[RegionNames.ShowSearchPatientRegion];
        _showSearchPatientView = (ShowSearchPatient)_region.Views.Where(t => t.GetType() == typeof(ShowSearchPatient)).FirstOrDefault();
 }


  public ShowSearchPatientViewModel(IApplicationCommands applicationCommands,IRegionManager regionManager)
  {
        this.ApplicationCommands = applicationCommands;
        _regionManager = regionManager;
  }

  /// <summary>
  /// 激活视图
  /// </summary>
  private void ActiveShowSearchPatient()
  {
       if (!_region.ActiveViews.Contains(_showSearchPatientView))
       {
           _region.Add(_showSearchPatientView);
       }         
  }
   
  /// <summary>
  /// 失效视图
  /// </summary>
   private async void DeactiveShowSearchPaitent()
   {
        _region.Remove(_showSearchPatientView);
        await Task.Delay(2000);
        IsShow = true;
   }

Los resultados son los siguientes:

de aquí WindowCommands cadena de herencia como: WindowCommands <- Barra de herramientas <- HeaderedItemsControl <- ItemsControl, por lo tanto, debido al impago de adaptadores Prism tiene ItemsControlRegionAdapter, por lo que la subclase hereda también su comportamiento

El enfoque aquí un resumen:

  • Cuando el módulo de carga acabada modular entrará en la región de vista implantado (consulte vista MedicineModule orden de carga)
  • Desde ContentControl contenido sólo puede mostrar un control, en la región del mismo puede ser controlado por un método de visualización que activan y vista Desactivar, el comportamiento es controlado por el ContentControlRegionAdapter adaptador
  • el control ItemsControl y sus hijos desde la pantalla de una colección de vista, la vista predeterminada de la colección completa está activa, esta vez no por formas de activar y desactivar el control (siendo dado), a través de la opción Agregar y Quitar para control que ver para demostrar que su comportamiento se debe a Control adaptador ItemsControlRegionAdapter
  • Selector de control no se ha mencionado aquí, porque también hereda de ItemsControl, por lo que SelectorRegionAdapter adaptador y el adaptador similar a ItemsControlRegionAdapter
  • Ver el estado de activación se puede controlar a través de la herencia de interfaz IActiveAware

IV. Adaptadores personalizado Región

Hemos dicho en la introducción, el área entera diagrama de modelo gerente, Prisma tiene un adaptador de tres por defecto la configuración regional: ItemsControlRegionAdapter, ContentControlRegionAdapter, SelectorRegionAdapter, y soporte para el adaptador región personalizada, ahora personalizamos los adaptadores mirada

1. Crear un adaptador personalizado

Nueva Clase UniformGridRegionAdapter.cs:

public class UniformGridRegionAdapter : RegionAdapterBase<UniformGrid>
{
    public UniformGridRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory)
    {

    }

    protected override void Adapt(IRegion region, UniformGrid regionTarget)
    {
        region.Views.CollectionChanged += (s, e) =>
        {
          if (e.Action==System.Collections.Specialized.NotifyCollectionChangedAction.Add)
          {
              foreach (FrameworkElement element in e.NewItems)
              {
                   regionTarget.Children.Add(element);
              }
          }
        };
    }

    protected override IRegion CreateRegion()
    {
        return new AllActiveRegion();
    }
 }

2. Regístrese mapas

App.cs:

protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
{
    base.ConfigureRegionAdapterMappings(regionAdapterMappings);
    regionAdapterMappings.RegisterMapping(typeof(UniformGrid),      Container.Resolve<UniformGridRegionAdapter>());//为UniformGrid控件注册适配器映射
}

3. Crear una zona para los controles

MainWindow.xaml:

    <UniformGrid Margin="5" prism:RegionManager.RegionName="UniformContentRegion" Columns="2">
        <Button Content="ActivePaientList" Margin="5" Command="{Binding ActivePaientListCommand}"/>
        <Button Content="DeactivePaientList" Margin="5" Command="{Binding DeactivePaientListCommand}"/>
        <Button Content="ActiveMedicineList" Margin="5" Command="{Binding ActiveMedicineListCommand}"/>
        <Button Content="DeactiveMedicineList" Margin="5" Command="{Binding DeactiveMedicineListCommand}"/>
     </UniformGrid>

4. Vista región implantada

Aquí está la manera ViewInjection:

MainWindowViewModel.cs

  void ExecuteLoadingCommand()
  {
         _regionManager = CommonServiceLocator.ServiceLocator.Current.GetInstance<IRegionManager>();

         var uniformContentRegion = _regionManager.Regions["UniformContentRegion"];
         var regionAdapterView1 = CommonServiceLocator.ServiceLocator.Current.GetInstance<RegionAdapterView1>();
         uniformContentRegion.Add(regionAdapterView1);
         var regionAdapterView2 = CommonServiceLocator.ServiceLocator.Current.GetInstance<RegionAdapterView2>();
         uniformContentRegion.Add(regionAdapterView2); 
  }

El efecto es como:

Podemos ver que creamos adaptadores para el área UniformGrid, y después del registro, podemos crear área de control UniformGrid, y se inyecta vista muestra, si no hay un adaptador en la región, que se está dando, la próxima vamos a explicar la base de la región de Región sistema de navegación prisma.

V. Fuente

 Por último, conecte todo el código fuente de demostración: PrismDemo Fuente

Supongo que te gusta

Origin www.cnblogs.com/ryzen/p/12605347.html
Recomendado
Clasificación