C# 如何在wpf中保持可见1秒,然后返回到隐藏在可见性中?

C# 如何在wpf中保持可见1秒,然后返回到隐藏在可见性中?,c#,.net,wpf,C#,.net,Wpf,我有一个滚动条的样式。 默认情况下,滚动条中的轨迹具有隐藏的可见性。 如果出现以下任一情况,则会将其更改为可见: -鼠标在滚动条上 -或者,用户当前正在使用滚轮滚动 一旦可见性条件不再满足,如何使轨迹保持可见1秒,然后返回隐藏 谢谢 <ControlTemplate x:Key="VerticalScrollBarTemplate" TargetType="{x:Type ScrollBar}"> <Grid Width="15"> <Bo

我有一个滚动条的样式。 默认情况下,滚动条中的轨迹具有隐藏的可见性。 如果出现以下任一情况,则会将其更改为可见: -鼠标在滚动条上 -或者,用户当前正在使用滚轮滚动 一旦可见性条件不再满足,如何使轨迹保持可见1秒,然后返回隐藏

谢谢

 <ControlTemplate x:Key="VerticalScrollBarTemplate" TargetType="{x:Type ScrollBar}">
    <Grid Width="15">
        <Border Opacity="0.7"/>
        <Track x:Name="PART_Track" 
            Width="12"
            MinHeight="20"
            Height="Auto"
            Margin="2"
            IsDirectionReversed="true" >
            <Track.DecreaseRepeatButton>
                <RepeatButton Style="{StaticResource ScrollBackgroundStyle}" Command="ScrollBar.LineUpCommand"  />
            </Track.DecreaseRepeatButton>
            <Track.IncreaseRepeatButton>
                <RepeatButton Style="{StaticResource ScrollBackgroundStyle}" Command="ScrollBar.LineDownCommand" />
            </Track.IncreaseRepeatButton>
            <Track.Thumb>
                <Thumb Name="Thumb" Visibility="Hidden" Style="{StaticResource ScrollBarThumbStyle}" />
            </Track.Thumb>
        </Track>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter TargetName="Thumb" Property="Visibility" Value="Visible"/>                
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

我尝试使用:

 <Storyboard x:Key="FadeInStoryboard">
    <DoubleAnimation Storyboard.TargetName="Thumb" 
             Storyboard.TargetProperty="Opacity"
             From="0" To="1"  Duration="0:0:0.5"/>
</Storyboard>
<Storyboard x:Key="FadeOutStoryboard" BeginTime="0:0:1">
        <DoubleAnimation Storyboard.TargetName="Thumb"
                 Storyboard.TargetProperty="Opacity"
                 From="1" To="0"  Duration="0:0:0.5" />
    </Storyboard>

<Trigger Property="IsMouseOver" Value="true">
                <Setter TargetName="Thumb" Property="Visibility" Value="Visible"/>
                <Trigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" />
                </Trigger.EnterActions>
                <Trigger.ExitActions><
                    <BeginStoryboard Storyboard="{StaticResource FadeOutStoryboard}" />
                </Trigger.ExitActions>
            </Trigger>

<
但这不会保持轨迹在1秒内可见,然后返回到隐藏状态,除非我在滚动条中默认设置轨迹的可见性为可见。
谢谢

问题在于您的
设置器
可见性
设置为
可见
。一旦
IsMouseOver
属性将值更改为false,触发器将自动将
可见性
设置回
隐藏
。要解决这个问题,您必须设置
可见性
属性的动画,并从触发器中删除
Setter

故事板示例:

<Storyboard x:Key="FadeInStoryboard">
    <ObjectAnimationUsingKeyFrames Duration="0:0:0" 
                                   Storyboard.TargetName="Thumb"
                                   Storyboard.TargetProperty="Visibility">
        <DiscreteObjectKeyFrame KeyTime="0%" Value="{x:Static Visibility.Visible}"/>
    </ObjectAnimationUsingKeyFrames>
    <DoubleAnimation Duration="0:0:0.5" From="0"
                     Storyboard.TargetName="Thumb" 
                     Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
<Storyboard x:Key="FadeOutStoryboard" >
    <DoubleAnimation Duration="0:0:0.5" From="1" BeginTime="0:0:1"
                     Storyboard.TargetName="Thumb" Storyboard.TargetProperty="Opacity"
                     To="0" />
    <ObjectAnimationUsingKeyFrames Duration="0:0:1" 
                                   Storyboard.TargetName="Thumb" 
                                   Storyboard.TargetProperty="Visibility">
        <DiscreteObjectKeyFrame KeyTime="100%" Value="{x:Static Visibility.Hidden}"/>
    </ObjectAnimationUsingKeyFrames>
</Storyboard>
将以下
DataTrigger
添加到
ScrollBar的
ControlTemplate
中: 注意:这会显式停止
开始脚本
s,您需要将
停止脚本
s添加到
控制模板
中现有的
触发器
,否则最后一个
触发器
将阻止第一个
触发器

<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=data:ScrollViewerEx}, Path=IsScrollingWithMouseWheel}" 
             Value="True">
    <DataTrigger.EnterActions>
        <StopStoryboard BeginStoryboardName="fadeOut"/>
        <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeIn"/>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="fadeIn"/>
        <BeginStoryboard Storyboard="{StaticResource FadeOutStoryboard}" Name="fadeOut"/>
    </DataTrigger.ExitActions>
</DataTrigger>
并创建一个类来定义中的附加属性,如下所示:

public static class ScrollViewerProperties {
    public static readonly DependencyProperty IsScrollingWithMouseWheelProperty = DependencyProperty.RegisterAttached(
        "IsScrollingWithMouseWheel", typeof (bool), typeof (ScrollViewerProperties), new PropertyMetadata(default(bool)));

    public static void SetIsScrollingWithMouseWheel(DependencyObject element, bool value) {
        element.SetValue(IsScrollingWithMouseWheelProperty, value);
    }

    public static bool GetIsScrollingWithMouseWheel(DependencyObject element) {
        return (bool) element.GetValue(IsScrollingWithMouseWheelProperty);
    }
}
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}},Path=(data:ScrollViewerProperties.IsScrollingWithMouseWheel)}" Value="True">
    <DataTrigger.EnterActions>
        <StopStoryboard BeginStoryboardName="fadeOut"/>
        <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeIn"/>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="fadeIn"/>
        <BeginStoryboard Storyboard="{StaticResource FadeOutStoryboard}" Name="fadeOut"/>
    </DataTrigger.ExitActions>
</DataTrigger>
并更新
滚动条
模板中的
数据触发器
,以使用如下附加属性:

public static class ScrollViewerProperties {
    public static readonly DependencyProperty IsScrollingWithMouseWheelProperty = DependencyProperty.RegisterAttached(
        "IsScrollingWithMouseWheel", typeof (bool), typeof (ScrollViewerProperties), new PropertyMetadata(default(bool)));

    public static void SetIsScrollingWithMouseWheel(DependencyObject element, bool value) {
        element.SetValue(IsScrollingWithMouseWheelProperty, value);
    }

    public static bool GetIsScrollingWithMouseWheel(DependencyObject element) {
        return (bool) element.GetValue(IsScrollingWithMouseWheelProperty);
    }
}
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}},Path=(data:ScrollViewerProperties.IsScrollingWithMouseWheel)}" Value="True">
    <DataTrigger.EnterActions>
        <StopStoryboard BeginStoryboardName="fadeOut"/>
        <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeIn"/>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="fadeIn"/>
        <BeginStoryboard Storyboard="{StaticResource FadeOutStoryboard}" Name="fadeOut"/>
    </DataTrigger.ExitActions>
</DataTrigger>

问题在于您的
设置器
可见性设置为
可见
。一旦
IsMouseOver
属性将值更改为false,触发器将自动将
可见性
设置回
隐藏
。要解决这个问题,您必须设置
可见性
属性的动画,并从触发器中删除
Setter

故事板示例:

<Storyboard x:Key="FadeInStoryboard">
    <ObjectAnimationUsingKeyFrames Duration="0:0:0" 
                                   Storyboard.TargetName="Thumb"
                                   Storyboard.TargetProperty="Visibility">
        <DiscreteObjectKeyFrame KeyTime="0%" Value="{x:Static Visibility.Visible}"/>
    </ObjectAnimationUsingKeyFrames>
    <DoubleAnimation Duration="0:0:0.5" From="0"
                     Storyboard.TargetName="Thumb" 
                     Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
<Storyboard x:Key="FadeOutStoryboard" >
    <DoubleAnimation Duration="0:0:0.5" From="1" BeginTime="0:0:1"
                     Storyboard.TargetName="Thumb" Storyboard.TargetProperty="Opacity"
                     To="0" />
    <ObjectAnimationUsingKeyFrames Duration="0:0:1" 
                                   Storyboard.TargetName="Thumb" 
                                   Storyboard.TargetProperty="Visibility">
        <DiscreteObjectKeyFrame KeyTime="100%" Value="{x:Static Visibility.Hidden}"/>
    </ObjectAnimationUsingKeyFrames>
</Storyboard>
将以下
数据触发器
添加到
滚动条的
控制模板
注意:这会显式停止
开始脚本
s,您需要将
停止脚本
s添加到
控制模板
中现有的
触发器
,否则最后一个
触发器
将阻止第一个
触发器

<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=data:ScrollViewerEx}, Path=IsScrollingWithMouseWheel}" 
             Value="True">
    <DataTrigger.EnterActions>
        <StopStoryboard BeginStoryboardName="fadeOut"/>
        <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeIn"/>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="fadeIn"/>
        <BeginStoryboard Storyboard="{StaticResource FadeOutStoryboard}" Name="fadeOut"/>
    </DataTrigger.ExitActions>
</DataTrigger>
并创建一个类来定义中的附加属性,如下所示:

public static class ScrollViewerProperties {
    public static readonly DependencyProperty IsScrollingWithMouseWheelProperty = DependencyProperty.RegisterAttached(
        "IsScrollingWithMouseWheel", typeof (bool), typeof (ScrollViewerProperties), new PropertyMetadata(default(bool)));

    public static void SetIsScrollingWithMouseWheel(DependencyObject element, bool value) {
        element.SetValue(IsScrollingWithMouseWheelProperty, value);
    }

    public static bool GetIsScrollingWithMouseWheel(DependencyObject element) {
        return (bool) element.GetValue(IsScrollingWithMouseWheelProperty);
    }
}
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}},Path=(data:ScrollViewerProperties.IsScrollingWithMouseWheel)}" Value="True">
    <DataTrigger.EnterActions>
        <StopStoryboard BeginStoryboardName="fadeOut"/>
        <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeIn"/>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="fadeIn"/>
        <BeginStoryboard Storyboard="{StaticResource FadeOutStoryboard}" Name="fadeOut"/>
    </DataTrigger.ExitActions>
</DataTrigger>
并更新
滚动条
模板中的
数据触发器
,以使用如下附加属性:

public static class ScrollViewerProperties {
    public static readonly DependencyProperty IsScrollingWithMouseWheelProperty = DependencyProperty.RegisterAttached(
        "IsScrollingWithMouseWheel", typeof (bool), typeof (ScrollViewerProperties), new PropertyMetadata(default(bool)));

    public static void SetIsScrollingWithMouseWheel(DependencyObject element, bool value) {
        element.SetValue(IsScrollingWithMouseWheelProperty, value);
    }

    public static bool GetIsScrollingWithMouseWheel(DependencyObject element) {
        return (bool) element.GetValue(IsScrollingWithMouseWheelProperty);
    }
}
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}},Path=(data:ScrollViewerProperties.IsScrollingWithMouseWheel)}" Value="True">
    <DataTrigger.EnterActions>
        <StopStoryboard BeginStoryboardName="fadeOut"/>
        <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeIn"/>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="fadeIn"/>
        <BeginStoryboard Storyboard="{StaticResource FadeOutStoryboard}" Name="fadeOut"/>
    </DataTrigger.ExitActions>
</DataTrigger>

只需完成一个精彩的@Roel van Westerop评论。 我试过自己编辑2。它工作得很好,除了一件小事。与仅使用DataTrigger不同,更好的方法是使用MultiDataTrigger,如下所示:

<MultiDataTrigger>
     <MultiDataTrigger.Conditions>
           <Condition Binding="{Binding RelativeSource=
                      {RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}},
                       Path=(data:ScrollViewerProperties.IsScrollingWithMouseWheel)}" Value="True"/>
           <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self},
                                        Path=IsMouseOver}" Value="False"/>                                
     </MultiDataTrigger.Conditions>
     <MultiDataTrigger.EnterActions>
          <StopStoryboard BeginStoryboardName="fadeOut"/>
          <BeginStoryboard Storyboard="
                                {StaticResource FadeInStoryboard}" Name="fadeIn"/>
      </MultiDataTrigger.EnterActions>
      <MultiDataTrigger.ExitActions>
           <StopStoryboard BeginStoryboardName="fadeIn"/>
           <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeOut"/>
      </MultiDataTrigger.ExitActions>
</MultiDataTrigger>


当您将鼠标放在滚动条上,并使用鼠标滚轮滚动内容时,此MultiDataTrigger修复了此错误(如果没有此multitrigger,滚动条将消失,即使有鼠标覆盖)

只是为了完成一条精彩的@Roel van Westerop评论。 我试过自己编辑2。它工作得很好,除了一件小事。与仅使用DataTrigger不同,更好的方法是使用MultiDataTrigger,如下所示:

<MultiDataTrigger>
     <MultiDataTrigger.Conditions>
           <Condition Binding="{Binding RelativeSource=
                      {RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}},
                       Path=(data:ScrollViewerProperties.IsScrollingWithMouseWheel)}" Value="True"/>
           <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self},
                                        Path=IsMouseOver}" Value="False"/>                                
     </MultiDataTrigger.Conditions>
     <MultiDataTrigger.EnterActions>
          <StopStoryboard BeginStoryboardName="fadeOut"/>
          <BeginStoryboard Storyboard="
                                {StaticResource FadeInStoryboard}" Name="fadeIn"/>
      </MultiDataTrigger.EnterActions>
      <MultiDataTrigger.ExitActions>
           <StopStoryboard BeginStoryboardName="fadeIn"/>
           <BeginStoryboard Storyboard="{StaticResource FadeInStoryboard}" Name="fadeOut"/>
      </MultiDataTrigger.ExitActions>
</MultiDataTrigger>


当您将鼠标放在滚动条上并使用鼠标滚轮滚动内容时,此MultiDataTrigger修复了此错误(如果没有此multitrigger,滚动条将消失,即使有鼠标覆盖)

当鼠标进入和离开滚动条时,您可以在一秒钟内将Thumb的不透明度属性从0设置为100%。感谢您及时回复FreddyFlares.FreddyFlares,我尝试过但没有效果当鼠标进入和离开滚动条时,您可以在一秒钟内将Thumb的不透明度属性从0设置为100%。感谢您的提示回复FreddyFlares.FreddyFlares,我尝试过但没有效果如果:用户当前正在使用滚轮滚动,您能帮助我将其更改为可见吗?。非常感谢你@乐先生编辑了答案,如果这对您有帮助,您能将此标记为答案吗?谢谢您的热情支持。您有没有不创建新类的解决方案?例如使用:。我正在你的路上测试!可以使用
事件触发器
,但仍需要一个属性来触发
滚动条中的行为
,请参见编辑#2@Roel我不知道为什么在不透明度为零时需要更改可见性,它无论如何都不可见,对吗?如果:用户当前正在使用滚轮滚动,您能帮助我将其更改为可见吗?。非常感谢你@乐先生编辑了答案,如果这对您有帮助,您能将此标记为答案吗?谢谢您的热情支持。您有没有不创建新类的解决方案?例如使用:。我正在你的路上测试!可以使用
EventTrigger
,但仍需要一个属性来触发