淡入/淡出mediaElement顶部的堆栈面板(两者都在网格中的同一单元格内)

本文关键字:网格 单元格 两者都 mediaElement 淡出 顶部 堆栈 淡入 | 更新日期: 2023-09-27 18:14:11

我是WPF的新手,我在这方面面临一个问题。我正在制作一个简单的视频应用程序,该应用程序有3列。第二列是一个gridsplitter,而第三列是一个MediaElement和一个StackPanel(包含视频控件)在它上面。

我想要实现的是当鼠标指针进入MediaElement时淡化StackPanel,当鼠标指针退出MediaElement时淡化StackPanel。然而,当鼠标指针进入StackPanel时,问题就出现了,这会触发淡出效果(MediaElement的MouseExit事件会发生)。

<Window x:Class="WPF_learningapp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:MyNamespace="clr-namespace:WPF_learningapp"
    Title="MiDrama" Height="350" Width="700" ResizeMode="CanResize">
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Custom assets/CustomScrollbar.xaml"></ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
        <MyNamespace:PausePlayBooleanConverter x:Key="PausePlayBooleanConverter" />
    </ResourceDictionary>
</Window.Resources>
<MyNamespace:GridControl>
    <Grid.ColumnDefinitions>
        <ColumnDefinition MinWidth="0" MaxWidth="300"/>
        <ColumnDefinition Width="1"/>
        <ColumnDefinition Width= "*">
        </ColumnDefinition>
    </Grid.ColumnDefinitions>
    <StackPanel/>
    <GridSplitter Grid.Column="1" Width="1" HorizontalAlignment="Stretch" />
    <MediaElement Grid.Column="2" Name="myMediaPlayer" LoadedBehavior="Manual" Stretch="Fill">
        <MediaElement.Triggers>
          <EventTrigger RoutedEvent="MouseEnter" >
             <BeginStoryboard>
                 <Storyboard>
                     <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VideoControlPanel"
                             From="0.0" To="1.0" Duration="0:0:1"/>
                 </Storyboard>
             </BeginStoryboard>
          </EventTrigger>
          <EventTrigger RoutedEvent="MouseLeave">
             <BeginStoryboard>
                 <Storyboard>
                     <DoubleAnimation Storyboard.TargetProperty="Opacity"           Storyboard.TargetName="VideoControlPanel"
                            From="1.0" To="0" Duration="0:0:1"/>
                 </Storyboard>
             </BeginStoryboard>
          </EventTrigger>
       </MediaElement.Triggers>
    </MediaElement>
    <StackPanel Name="VideoControlPanel" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="59" Margin="55,0,41,4" Background="Transparent">
        <Slider Name="VideoSlider" Thumb.DragStarted="slider_DragStarted"  Thumb.DragCompleted="slider_DragCompleted" Margin="0,0,0,5"
                IsMoveToPointEnabled="True" ValueChanged="slider_ValueChanged"/>
        <WrapPanel HorizontalAlignment="Center">
            <Button Content="{Binding Path=isPlaying, Converter={StaticResource PausePlayBooleanConverter}}" Height="34" Width="50" Margin="5 0" Name="playpause_Btn" Click="playpause_Btn_Click"/>
            <Button Height="34" Width="50" Content="Stop" Margin="5 0" Name="stop_Btn" Click="stop_Btn_Click"/>
        </WrapPanel>
    </StackPanel>
</MyNamespace:GridControl>

我试着将所有东西封装在网格内的画布中,但控制面板将无法正确调整大小。甚至在网格列上实现事件触发器似乎也不起作用。有办法做到这一点吗?请建议。

淡入/淡出mediaElement顶部的堆栈面板(两者都在网格中的同一单元格内)

我想说的是,你应该把EventTrigger for MouseLeave放在StackPanel上,或者放在StackPanel的内容上,而不是放在MediaElement上。

编辑

好的,我认为stackpanel覆盖了整个medialelement(我没有看到height prop)。

一个解决方案是将mediaelement和stackpanel放在某种类型的内容控件中,如下面的例子所示:

<Window x:Class="SO40188046.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SO40188046"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
  <Border Background="Blue">
    <Border.Triggers>
      <EventTrigger RoutedEvent="MouseEnter">
        <BeginStoryboard>
          <Storyboard>
            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VideoControlPanel" From="0.0" To="1.0" Duration="0:0:1"/>
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>
      <EventTrigger RoutedEvent="MouseLeave">
        <BeginStoryboard>
          <Storyboard>
            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VideoControlPanel" From="1.0" To="0" Duration="0:0:1"/>
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>
    </Border.Triggers>
    <Grid>
      <MediaElement Source="SOME MEDIA URI" />
      <Border Name="VideoControlPanel" Background="Red" Height="100" VerticalAlignment="Bottom" Opacity="0" />
    </Grid>
  </Border>
</Window>

编辑2:

在这里我已经修改了你自己的答案,所以不需要后面的代码来调整和定位控件。我用ContentControl替换了Canvas,并替换了其他一些控件。但整体布局是相同的:

<Window x:Class="WPF_learningapp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:MyNamespace="clr-namespace:WPF_learningapp"
        Title="MiDrama" Height="350" Width="700" ResizeMode="CanResize">
  <Window.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Custom assets/CustomScrollbar.xaml"></ResourceDictionary>
      </ResourceDictionary.MergedDictionaries>
      <MyNamespace:PausePlayBooleanConverter x:Key="PausePlayBooleanConverter" />
    </ResourceDictionary>
  </Window.Resources>
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition MinWidth="0" MaxWidth="300"/>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width= "*">
      </ColumnDefinition>
    </Grid.ColumnDefinitions>
    <StackPanel/>
    <GridSplitter Grid.Column="1" Width="4" HorizontalAlignment="Center" VerticalAlignment="Stretch" />
    <ContentControl Grid.Column="2" Background="AliceBlue">
      <ContentControl.Triggers>
        <EventTrigger RoutedEvent="MouseEnter" >
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation 
                Storyboard.TargetProperty="Opacity" 
                Storyboard.TargetName="VideoControlPanel"
                From="0.0" 
                To="1.0" 
                Duration="0:0:1"/>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="MouseLeave">
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation 
                Storyboard.TargetProperty="Opacity" 
                Storyboard.TargetName="VideoControlPanel"
                From="1.0" 
                To="0" 
                Duration="0:0:1"/>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </ContentControl.Triggers>
      <Grid>
        <MediaElement 
          Name="myMediaPlayer" 
          Stretch="Fill"  />
        <Grid Name="VideoControlPanel" VerticalAlignment="Bottom" Height="60" Background="Transparent" Opacity="0">
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
          </Grid.RowDefinitions>
          <Slider 
            Name="VideoSlider" 
            Grid.Column="0"
            Grid.ColumnSpan="2"
            Thumb.DragStarted="slider_DragStarted"  
            Thumb.DragCompleted="slider_DragCompleted" 
            Margin="10,5"
            IsMoveToPointEnabled="True" 
            ValueChanged="slider_ValueChanged"/>
          <Button 
            Grid.Column="0"
            Grid.Row="1"
            HorizontalAlignment="Right"
            Content="Play" 
            Height="26" 
            Width="50" 
            Name="playpause_Btn" 
            Click="playpause_Btn_Click"/>
          <Button 
            Grid.Column="1"
            Grid.Row="1"
            HorizontalAlignment="Left"
            Height="26" 
            Width="50"
            Content="Stop"
            Name="stop_Btn" 
            Click="stop_Btn_Click"/>
        </Grid>
      </Grid>
    </ContentControl>
  </Grid>
</Window>

这就是上述问题的解决方案。把所有的东西都放在一个网格单元内的画布内(我认为这是唯一一个容易与重叠控件一起工作的容器)。

<Window x:Class="WPF_learningapp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:MyNamespace="clr-namespace:WPF_learningapp"
        Title="MiDrama" Height="350" Width="700" ResizeMode="CanResize">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Custom assets/CustomScrollbar.xaml"></ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
            <MyNamespace:PausePlayBooleanConverter x:Key="PausePlayBooleanConverter" />
        </ResourceDictionary>
    </Window.Resources>
    <MyNamespace:GridControl>
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="0" MaxWidth="300"/>
            <ColumnDefinition Width="1"/>
            <ColumnDefinition Width= "*">
            </ColumnDefinition>
        </Grid.ColumnDefinitions>
        <StackPanel/>
        <GridSplitter Grid.Column="1" Width="1" HorizontalAlignment="Stretch" />
        <Canvas Grid.Column="2" Name="VideoCanvas" SizeChanged="VideoCanvas_sizeChanged" Background="AliceBlue">
            <Canvas.Triggers>
                <EventTrigger RoutedEvent="MouseEnter" >
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VideoControlPanel"
                             From="0.0" To="1.0" Duration="0:0:1"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VideoControlPanel"
                            From="1.0" To="0" Duration="0:0:1"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Canvas.Triggers>
            <MediaElement Grid.Column="2" Name="myMediaPlayer" LoadedBehavior="Manual" Stretch="Fill" Height="{Binding Path=ActualHeight, ElementName=VideoCanvas}"  Width="{Binding Path=ActualWidth, ElementName=VideoCanvas}"/>
            <StackPanel Name="VideoControlPanel" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="59" Background="Transparent" Canvas.Left="10" Canvas.Top="250" Width="371">
                <Slider Name="VideoSlider" Thumb.DragStarted="slider_DragStarted"  Thumb.DragCompleted="slider_DragCompleted" Margin="0,0,0,5"
                    IsMoveToPointEnabled="True" ValueChanged="slider_ValueChanged"/>
                <WrapPanel HorizontalAlignment="Center">
                    <Button Content="{Binding Path=isPlaying, Converter={StaticResource PausePlayBooleanConverter}}" Height="34" Width="50" Margin="5 0" Name="playpause_Btn" Click="playpause_Btn_Click"/>
                    <Button Height="34" Width="50" Content="Stop" Margin="5 0" Name="stop_Btn" Click="stop_Btn_Click"/>
                </WrapPanel>
            </StackPanel>
        </Canvas>
    </MyNamespace:GridControl>
</Window>