Как я могу динамически изменить какой элемент управления я использую в MVVM XAML - PullRequest
0 голосов
/ 25 сентября 2019

Я пишу простое приложение, которое использует VLC для воспроизведения видео.Обычно это было бы простым решением, но есть побочные эффекты практически для всех библиотек VLC в настоящее время;Vlc.DotNet.WPF великолепен, но имеет побочный эффект: интенсивность использования процессора, но решает проблемы с многоуровневым видео, а LibVLCSharp.WPF намного лучше с загрузкой процессора, но имеет проблемы с многоуровневым видео (проблемы воздушного пространства).Итак, я хочу иметь возможность разрабатывать свое приложение, чтобы позволить мне выбирать, какую библиотеку видео я использую для воспроизведения видео, чтобы я мог управлять компромиссами двух средств визуализации в зависимости от аппаратных и ситуационных требований, которые у меня есть.

Каждая библиотека предоставляет пользовательский элемент управления UserControl для отображения видео в представлении.LibVLCSharp предоставляет LibVLCSharp.WPF.VideoView, а Vlc.DotNet.WPF - Vlc.DotNet.Wpf.VlcControl.

. Я структурировал свой код для независимого отображения каждого из них следующим образом:

Класс управления для использования VlcDotNetWpf:

public class vlcPlayerDotNet : Vlc.DotNet.Wpf.VlcControl
{
   public vlcPlayerDotNet() {}
   ~vlcPlayerDotNet()
   {
      // class-specific cleanup routines
   }

   public void PlayVideo()
   {
      // class-specific video playback code to play Source video
   }

   // Dependency Properties
   public static readonly DependencyProperty SourceProperty =
      DependencyProperty.Register(
      "Source", typeof(string),
      typeof(vlcPlayerDotNet)
   );
   public string Source
   {
      get { return (string)GetValue(SourceProperty); }
      set { SetValue(SourceProperty, value); }
   } 

   /*
      ... and so on, for multiple dependency properties
   */
}

И класс Control для использования LibVlcSharp.Wpf:

public class vlcPlayerLibVLCSharp : LibVLCSharp.WPF.VideoView
{
   public vlcPlayerLibVLCSharp() {}
   ~vlcPlayerLibVLCSharp()
   {
      // class-specific cleanup routines
   }

   public void PlayVideo()
   {
      // class-specific video playback code to play Source video
   }

   // Dependency Properties
   public static readonly DependencyProperty SourceProperty =
      DependencyProperty.Register(
      "Source", typeof(string),
      typeof(vlcPlayerLibVLCSharp)
   );
   public string Source
   {
      get { return (string)GetValue(SourceProperty); }
      set { SetValue(SourceProperty, value); }
   } 

   /*
      ... and so on, for multiple dependency properties
   */
}

В моей ViewModel у меня есть несколько необходимых входов, а именно:

   private string animationFile;
   public string AnimationFile
   {
      get { return animationFile; }
      set { SetProperty(ref animationFile, value); }
   }

Тогдав моем представлении я определяю, какой элемент управления видео я хочу использовать - например, если я использую проигрыватель LibVLCSharp, я использую следующее:

   <Grid>
      <local:vlcPlayerLibVLCSharp 
         Grid.Column="0" Grid.Row="0"                 
         HorizontalAlignment="Center" VerticalAlignment="Center" 
         Height="720" Width="1280"
         Source="{Binding AnimationFile}" LoadedBehavior="Play"  
         MediaEnded="animationPlayer_MediaEnded" 
         MediaFailed="animationPlayer_MediaFailed" 
         x:Name="vlcPlayer"/>
   </Grid>

и т. д. для другого проигрывателя.

Чего я НЕ ХОЧУ, так это чтобы два View UserControls были сложены и свернуты;Я хочу иметь возможность иметь ОДИН View UserControl в представлении и иметь возможность динамически выбирать, какой UserControl фактически используется в представлении.Моя цель - иметь простой вид, и было бы замечательно, если бы я мог позже добавить еще один элемент управления без изменения вида (но это не нарушитель правил).

Я исследовал использование ContentControl в представлении для хранения видео UserControl (ов), но я не мог понять, как обращаться со свойствами зависимости, которые необходимо передать в элемент управления.Я также посмотрел на DataTemplate и DataTemplateSelector, но все примеры, которые я нашел, имеют дело со списками, и мне трудно сделать концептуальный переход от списка к этим производным элементам управления.

Любой совет о том, как спроектировать мой код, чтобы разрешить этот обмен под капотом, приветствуется!

1 Ответ

1 голос
/ 25 сентября 2019

Вы можете использовать элементы управления контентом и шаблоны данных.

. В родительском окне задайте шаблоны данных для каждого видеопроигрывателя.

<Window ...
        ...>

    <Window.Resources>
        <DataTemplate DataType="{x:Type viewModels:LibSharpViewModel}">
            <views:LibSharpView/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModels:VlcViewModel}">
            <views:VlcView/>
        </DataTemplate>

    </Window.Resources>

    <Grid>        
        <ContentControl  Content="{Binding SelectedVideoPlayerViewModel}"/>               
    </Grid>
</Window>

Затем определите представления Vlc и LibSharp в отдельном xaml.файлы.

Вы можете создать базовый класс для моделей просмотра видеопроигрывателя, которые определяют необходимые свойства зависимостей, от которых будут наследоваться виртуальные машины Vlc и LibSharp.

В виртуальной машине родительского окна вы можете определить, какой проигрыватель использовать, основываясь на ваших аппаратных критериях, и настроить SelectedVideoPlayerViewModel, чтобы выбрать, какой элемент управления отображается в элементе управления содержимым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...