簡體   English   中英

如何動態更改我在 MVVM XAML 中使用的控件

[英]How can I dynamically change what control I'm using within MVVM XAML

我正在編寫一個使用 VLC 播放視頻的簡單應用程序。 這通常是一個簡單的解決方案,但目前幾乎所有的 VLC 庫都有副作用; Vlc.DotNet.WPF 很棒,但它有一個副作用,它是 CPU 密集型的,但解決了分層視頻的問題,而 LibVLCSharp.WPF 在 CPU 利用率方面要好得多,但在分層視頻方面存在問題(空域問題)。 因此,我希望能夠構建我的應用程序以允許我切換我使用哪個視頻庫來播放視頻,以便我可以根據我的硬件和情境要求來管理兩個渲染器的權衡。

每個庫都提供了一個自定義用戶控件,用於在視圖中顯示視頻。 LibVLCSharp 提供LibVLCSharp.WPF.VideoView和 Vlc.DotNet.WPF 提供Vlc.DotNet.Wpf.VlcControl

我已經構建了我的代碼以通過以下方式獨立顯示其中的每一個:

控制 Class 以使用 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
   */
}

並控制 class 使用 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 UserControl; 我希望能夠在視圖中擁有一個視圖用戶控件,並能夠動態選擇視圖中實際使用的用戶控件。 我的目標是有一個簡單的視圖,如果我以后可以在不更改視圖的情況下添加另一個控件,那就太棒了(但這不是一個破壞者)。

我已經調查在視圖中使用ContentControl來包含視頻 UserControl,但我無法弄清楚如何處理需要傳遞給控件的依賴屬性。 我還查看了DataTemplateDataTemplateSelector ,但我發現的所有示例都處理列表框,我很難從列表框到這些派生控件的概念飛躍。

任何關於如何構建我的代碼以允許在引擎蓋下進行交換的建議都值得贊賞!

您可以使用內容控件和數據模板

在您的父級 window 中定義每個視頻播放器的數據模板。

<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>

然后在單獨的 xaml 文件中定義 Vlc 和 LibSharp 視圖。

您可以為視頻播放器視圖模型創建基本 class,這些視圖模型定義了 Vlc 和 LibSharp VM 將從中繼承的所需依賴項屬性。

在父窗口的 VM 中,您可以根據您的硬件條件確定使用哪個播放器,並設置 SelectedVideoPlayerViewModel 以切換在內容控件中顯示哪個控件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM