简体   繁体   English

如何动态更改我在 MVVM XAML 中使用的控件

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

I am writing a simple application that uses VLC to play a video.我正在编写一个使用 VLC 播放视频的简单应用程序。 This would normally be a simple solution, but there are side-effects to virtually all VLC libraries currently out there;这通常是一个简单的解决方案,但目前几乎所有的 VLC 库都有副作用; Vlc.DotNet.WPF is great but it has a side-effect that it is CPU intensive but solves problems with layering videos, and LibVLCSharp.WPF is much better with CPU utilization but has problems with layering videos (airspace issues). Vlc.DotNet.WPF 很棒,但它有一个副作用,它是 CPU 密集型的,但解决了分层视频的问题,而 LibVLCSharp.WPF 在 CPU 利用率方面要好得多,但在分层视频方面存在问题(空域问题)。 So, I want to be able to architect my application to allow me to switch which video library I'm using to play the video so that I can manage the trade-offs of the two renderers depending on the hardware and situational requirements I have.因此,我希望能够构建我的应用程序以允许我切换我使用哪个视频库来播放视频,以便我可以根据我的硬件和情境要求来管理两个渲染器的权衡。

Each library provides a custom UserControl for use to display a video within a View.每个库都提供了一个自定义用户控件,用于在视图中显示视频。 LibVLCSharp provides LibVLCSharp.WPF.VideoView and Vlc.DotNet.WPF provides Vlc.DotNet.Wpf.VlcControl . LibVLCSharp 提供LibVLCSharp.WPF.VideoView和 Vlc.DotNet.WPF 提供Vlc.DotNet.Wpf.VlcControl

I've structured my code to display each of these independently in the following way:我已经构建了我的代码以通过以下方式独立显示其中的每一个:

Control Class for using VlcDotNetWpf:控制 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
   */
}

And Control class for using LibVlcSharp.Wpf:并控制 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
   */
}

In my ViewModel I have a few needed inputs, namely:在我的 ViewModel 中,我有一些需要的输入,即:

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

Then, in my View, I define which video control I want to use - for example, if I am using the LibVLCSharp player I use the following:然后,在我的视图中,我定义了我想要使用的视频控件 - 例如,如果我使用的是 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>

And so on for the other player.其他玩家依此类推。

What I DO NOT want is to have two View UserControls stacked and collapsed;我不想要的是堆叠和折叠两个 View UserControl; I want to be able to have ONE View UserControl in the View and be able to dynamically choose which UserControl is actually being used within the View.我希望能够在视图中拥有一个视图用户控件,并能够动态选择视图中实际使用的用户控件。 My goal is to have a straightforward View, and it would be amazing if I could later add another Control without changing the View (but it's not a dealbreaker).我的目标是有一个简单的视图,如果我以后可以在不更改视图的情况下添加另一个控件,那就太棒了(但这不是一个破坏者)。

I have investigated using a ContentControl in the View to contain the video UserControl(s), but I couldn't figure out how to handle the Dependency Properties that need to be passed to the Control.我已经调查在视图中使用ContentControl来包含视频 UserControl,但我无法弄清楚如何处理需要传递给控件的依赖属性。 I've also looked at DataTemplate and DataTemplateSelector but all of the examples I've found deal with List Boxes and I'm having a hard time making the conceptual leap from the listbox to these derived controls.我还查看了DataTemplateDataTemplateSelector ,但我发现的所有示例都处理列表框,我很难从列表框到这些派生控件的概念飞跃。

Any advice on how to architect my code to allow this swap under the hood is appreciated!任何关于如何构建我的代码以允许在引擎盖下进行交换的建议都值得赞赏!

You can use a content control and data templates您可以使用内容控件和数据模板

In your parent window define the data templates for each video player.在您的父级 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>

Then define the Vlc and LibSharp views in separate xaml files.然后在单独的 xaml 文件中定义 Vlc 和 LibSharp 视图。

You can create a base class for the video player viewmodels that define the required dependency properties that the Vlc and LibSharp VM's will inherit from.您可以为视频播放器视图模型创建基本 class,这些视图模型定义了 Vlc 和 LibSharp VM 将从中继承的所需依赖项属性。

In the parent window's VM you can determine which player to use based on your hardware criteria, and set the SelectedVideoPlayerViewModel to switch which control is displayed in the content control.在父窗口的 VM 中,您可以根据您的硬件条件确定使用哪个播放器,并设置 SelectedVideoPlayerViewModel 以切换在内容控件中显示哪个控件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用MVVM和Xamarin在XAML中动态更改图像源 - How to change an image source dynamically in XAML using MVVM with Xamarin 如何使用MVVM从其他xaml页面进行属性更改? - How can I make a property change from a different xaml Page with the use of MVVM? 如何自动检测我正在使用的控制油漆事件? - How can I automatically detect what control paint event I'm using? 如何将WPF控件动态地更改为另一个? - How I can dynamically change a WPF control into another? 如何在xaml中使用ICommand更改按钮的标签? - How can I change the label of the button using ICommand in xaml? 如何在用户控件库的XAML中访问资源图像? - How can I access a resource image within XAML in a user control library? 在C#中,如何使用numericupdown控件动态地更改Solidbrush颜色? - In C#, how can I change a solidbrush color dynamically using numericupdown control? 我如何在不同的应用程序状态下管理我的计时器,我正在使用 MVVM 方法? - How can I manage my timer on different application states, I'm using MVVM approach? 如何在CommandBar中动态更改图像的来源? - How can I dynamically change the Source of an Image within a CommandBar? 如何通过使用MVVM在Prism(+ MEF)视图中通过特定控件的可用性来控制WPF 4.5 Ribbons上下文选项卡的可见性? - How do I control a WPF 4.5 Ribbons contextual tab visibility by availability of a particular control within a Prism (+ MEF) view using MVVM?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM