【问题标题】:VisualBrush (linked to VLC) doesn't change on TabControl selection changeVisualBrush(链接到 VLC)在 TabControl 选择更改时不会更改
【发布时间】:2014-10-01 21:49:37
【问题描述】:

我对视觉画笔(通过 VLC.DotNet 链接到 VLC 播放器)和选项卡控件的组合有一种奇怪的体验。我使用 VLC 播放器创建了一个自定义控件来观看 RTSP 流,并在给定窗口中有多个这样的控件。

问题是,如果我将所有控件放在列表视图中,它们都会正确显示。但是,如果我将它们放在选项卡控件中,那么它总是显示第一个选择的选项卡项的流,无论我当前在哪个选项卡上。控件中的其他所有内容(标签等)都会正确更改,但视觉画笔绘制的部分不会。

我的控件的视图定义为:

<UserControl x:Class="myApp.View.CameraMonitorView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Wpf="clr-namespace:Vlc.DotNet.Wpf;assembly=Vlc.DotNet.Wpf"
             Loaded="UserControl_Loaded">
    <DockPanel>
        <Label Content="{Binding Name}" DockPanel.Dock="Bottom"/>
        <Grid Margin="3">
            <Grid.Background>
                <VisualBrush Stretch="Uniform">
                    <VisualBrush.Visual>
                        <Image Source="{Binding VideoSource, ElementName=vlcControl}"/>
                        <!--<Image Source="{Binding Image}" /> -->
                    </VisualBrush.Visual>
                </VisualBrush>
            </Grid.Background>
            <Wpf:VlcControl x:Name="vlcControl" Margin="3"/>
        </Grid>
    </DockPanel>
</UserControl>

视图后面的代码开始播放 RTSP,但我认为该代码不会帮助解决这个问题。

同时 ViewModel(为了便于查看而被剥离)只是:

class CameraMonitorViewModel : ViewModelBase
{
    public CameraMonitorViewModel(string name, string image)
    {
        Name = name;
        Image = image;
    }

    public string Name {get; set;}
    public string Image { get; set; }
}

我有一个数据模板定义为:

<DataTemplate DataType="{x:Type vm:CameraMonitorViewModel}">
    <v:CameraMonitorView HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</DataTemplate>

全窗口视图模型有一个称为 Monitors 的 ObservableCollection,视图显示:

<TabControl ItemsSource="{Binding Monitors}" SelectedIndex="0" Height="300">
    <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
            <Setter Property="Header" Value="{Binding Name}"/>
            <Setter Property="Content" Value="{Binding}"/>
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>
<ListView ItemsSource="{Binding Monitors}" Height="300" />

ListView 正确显示来自每个摄像头的不同图像。选项卡项将始终显示相同的相机,但当我单击不同的选项卡时,控件的标签项会发生变化。此外,如果我将 VLC 控件图像的数据绑定替换为已注释掉的静态图像对象(其源是通过视图模型设置的),那么当我单击不同的选项卡时,图像将正确更改。

我真的很困惑,如果能提供任何帮助,我将不胜感激。

【问题讨论】:

  • 尝试删除'SelectedIndex="0"'
  • @h.alex 不走运。删除该行意味着最初没有选择任何选项卡。一旦我选择了一个,该相机的视图就会“卡住”,成为唯一会显示的视图。
  • 天哪。一旦加载了父用户控件,我就开始播放 VLC 控件。而且我刚刚检查过,只有一个控件从选项卡控件中加载(并且只有在我没有选定索引的情况下单击选项卡之后)。所以我完全错过了这个问题。感谢 h.alex 帮我找到这个>

标签: c# wpf tabcontrol vlc visualbrush


【解决方案1】:

是的,正如我在对问题的评论中指出的那样,问题是我正在根据控件的 Loaded 事件开始播放流。但它似乎在第二个选项卡之后没有被触发,可能是因为 Rachel 在这里提到的:Loaded event doesn't fire for the 4th TabControl tab(因为它重用了模板而不是加载多个模板)。

【讨论】:

  • 您可以将 IsSelected 属性添加到您的视图模型,删除 SelectedIndex = 0,而是使用 SelectedItem = {Binding SelectedMonitor},然后将 SelectedMonitor 属性添加到您的主视图模型(具有Monitors 属性)并在 SelectedMonitor 的设置器中设置所选监视器的 IsSelected,并将启动它的代码添加到 IsSelected 属性设置器而不是 Loaded 事件。
  • @h.alex 所以唯一的问题是播放流的代码实际上需要 VLC 控件,而 ViewModel 无权访问(MVVM 等等)。而且我还想让所有流同时运行(相对而言,它们不会吸收那么多带宽,而且启动时间有点过长)。老实说,我想要多个 VLC 控件,tabcontrol 显然不想给我。所以我可能不得不找到一个解决方案,涉及到 tabcontrol 以外的东西。
  • 哦。我懂了。请查看this。它应该有助于从 TabControl 获取多个 VLC 控件。除此之外,在这种情况下,我个人会说可以将控件实例放入您的 VM 中。使用 VLC 控件的加载事件,它的 DataContext 应该是您的 VM,并将其传递给 VM。如果你愿意:)
  • @h.alex 谢谢。我找到了那个代码项目,但很高兴能确认这一点以及获得对 VM 中控件的访问权限(我有另一种类似的情况,我做了你所描述的事情,感觉有点脏)。谢谢,祝你好运!
  • 我在生产应用程序中使用该代码项目,效果很好。没问题,干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多