【问题标题】:Fade in/out a stack panel on top of a mediaElement (both are within the same cell in a grid)淡入/淡出 mediaElement 顶部的堆栈面板(两者都在网格中的同一单元格内)
【发布时间】:2016-10-22 03:35:34
【问题描述】:

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

我尝试将所有内容封装在网格内的画布中,但控制面板无法正确调整大小。即使在网格列上实现事件触发器似乎也不起作用。有没有办法做到这一点?请指教。

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    我会说您应该将 MouseLeave 的 EventTrigger 放在 StackPanel 上,或者放在 StackPanel 的内容上 - 而不是放在 MediaElement 上。

    编辑

    好的,我认为 stackpanel 覆盖了整个中间元素(我没有看到 height 属性)。

    一种解决方案可能是将媒体元素和堆栈面板放置在某种内容控件中,如下例所示:

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

    【讨论】:

    • 我做不到,StackPanel 只是网格内的一小部分,我希望它在我进入网格后出现。唯一覆盖整个网格的控件是 MediaElement。
    • ??谁是你为什么要低调?
    • 我更新了我的 xaml 代码。我不认为画边框会起作用,我需要动画, 1. 鼠标进入第三列,显示 StackPanel。 2.鼠标退出第三列,移除StackPanel。
    • @Ytan:但边框只是内容控件的一个示例。例如,您可以从 复制我的所有代码并将其放入第三列并将 Border 更改为 ContentControl 或您想要的任何内容,它会按照您描述的方式工作...您必须思考沿着我们的答案之路为您自己,否则不值得麻烦:-)
    • 我明白了,最后我只是将第三列中的所有内容都封装在了一个画布中,并手动调整了里面的所有内容。我认为会有一个更简单的选择。我也更新了我的 UI xaml。
    【解决方案2】:

    这是上述问题的解决方案。将所有内容放在网格单元格内的画布中(我认为这是唯一一个易于使用重叠控件的容器)。

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

    【讨论】:

    • 在我的回答中查看我的 EDIT 2
    猜你喜欢
    • 2011-04-28
    • 1970-01-01
    • 2019-07-22
    • 2014-05-08
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    相关资源
    最近更新 更多