【问题标题】:Blink an image from ViewModel从 ViewModel 闪烁图像
【发布时间】:2015-06-24 08:41:57
【问题描述】:

我想在用户点击一个按钮时向他们提供一些反馈,这会启动一个可能很长的请求。

我正在使用带有 mvvm 的 WPF,我想开始闪烁单击的图像。

这是 XAML 代码:

<Button Style="{DynamicResource BtnToolBar}" Command="{Binding refreshAll}">
     <Image x:Name="imgUpd" Style="{DynamicResource ImageStyleUpd}" ToolTip="{StaticResource UpdateData}"/>
</Button>

我想要类似的东西:

isBlinking="{Binding isBlinking}"

它存在吗?如何从 ViewModel 制作闪烁的图像?有可能吗?

编辑:我用我找到的solution 写了这个。

【问题讨论】:

    标签: wpf xaml mvvm viewmodel


    【解决方案1】:

    您可以使用 viewmodel 开始闪烁。做你想做的事,你需要:

    • 为您的 ImageStyleUpd 样式添加新的 DataTrigger
    • 使用“True”值将其绑定到您的 isBlinking 属性
    • 在触发器中,您可以根据需要为图像设置动画(例如,更改图像的不透明度)

    示例

    <Style x:Key="ImageStyleUpd" TargetType="{x:Type Image}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsBlinking}" Value="True">
                <DataTrigger.EnterActions>
                    <BeginStoryboard x:Name="blinking">
                        <Storyboard RepeatBehavior="Forever">
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" AutoReverse="True"
                                             To="0.5" Duration="0:0:0.5">
                            </DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <StopStoryboard BeginStoryboardName="blinking"/>
                </DataTrigger.ExitActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    

    希望,它会有所帮助。

    【讨论】:

    【解决方案2】:

    闪烁通常是视图中的动画,可以通过视图模型中的IsBlinking 属性启动/停止。您可以通过改变DropShadowEffect(平滑闪烁)或简单切换两个画笔来实现闪烁效果:

    <DataTrigger Binding="{Binding IsBlinking}" Value="True">
        <DataTrigger.EnterActions>
            <BeginStoryboard x:Name="blinking">
                <Storyboard RepeatBehavior="Forever">
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="item"
                                                   Storyboard.TargetProperty="Background">
                        <DiscreteObjectKeyFrame Value="Red" KeyTime="0:0:0"/>
                        <DiscreteObjectKeyFrame Value="White" KeyTime="0:0:0.3"/>
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.5"/>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </DataTrigger.EnterActions>
        <DataTrigger.ExitActions>
            <StopStoryboard BeginStoryboardName="blinking"/>
        </DataTrigger.ExitActions>
    </DataTrigger>
    

    item - 是您想要为Background(或Foreground/Fill等)设置动画的一些视觉对象。

    <!-- to example path, use Storyboard.TargetProperty="Fill" -->
    <Path x:Name="item" Fill="SomeDefaultNonBlinkingBrush" ... />
    

    【讨论】:

      【解决方案3】:

      我喜欢在一个行为中做这种事情,它是可重用的,你可以在任何UIElement上设置这个属性。

      public static class FlickrBehavior
      {
          #region IsFlickering
      
          public static bool GetIsFlickering(UIElement element)
          {
              return (bool)element.GetValue(IsFlickeringProperty);
          }
      
          public static void SetIsFlickering(UIElement element, bool value)
          {
              element.SetValue(IsFlickeringProperty, value);
          }
      
          public static readonly DependencyProperty IsFlickeringProperty =
              DependencyProperty.RegisterAttached("IsFlickering", typeof(bool), typeof(FlickrBehavior), new UIPropertyMetadata(false, OnIsFlickeringChanged));
      
          static void OnIsFlickeringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              if ((bool)e.NewValue)
                  StartAnimation(d as UIElement);
              else
                  StopAnimation(d as UIElement);
          }
      
          private static void StartAnimation(UIElement element)
          {
              DoubleAnimation da = new DoubleAnimation();
              da.From = 1;
              da.To = 0;
              da.Duration = new Duration(TimeSpan.FromSeconds(2));
              da.AutoReverse = true;
              da.RepeatBehavior = RepeatBehavior.Forever;
              element.BeginAnimation(UIElement.OpacityProperty, da);
          }
      
          private static void StopAnimation(UIElement element)
          {
              element.BeginAnimation(UIElement.OpacityProperty, null);
          }
      
          #endregion
      }
      

      【讨论】:

        【解决方案4】:

        与@Novitchi 的回答类似,我也想创建一个带有附加属性的行为。但我会将行为附加到mouse click

        所以你可以创建如下行为:

        public static class BlinkingBehaviour
        {
            public static bool GetIsBlinkingWhenClick(UIElement element)
            {
                return (bool)element.GetValue(IsBlinkingWhenClickProperty);
            }
        
            public static void SetIsBlinkingWhenClick(UIElement element, bool value)
            {
                element.SetValue(IsBlinkingWhenClickProperty, value);
            }
        
            public static readonly DependencyProperty IsBlinkingWhenClickProperty =
                DependencyProperty.RegisterAttached(
                   "IsBlinkingWhenClick", 
                   typeof(bool), 
                   typeof(BlinkingBehaviour), 
                   new FrameworkPropertyMetadata(false, OnIsBlinkingWhenClickChanged));
        
            static void OnIsBlinkingWhenClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if ((bool)e.NewValue)
                {
                    (d as UIElement).PreviewMouseLeftButtonDown -= BlinkingWhenClickBehavior_PreviewMouseLeftButtonDown;
                    (d as UIElement).PreviewMouseLeftButtonDown += BlinkingWhenClickBehavior_PreviewMouseLeftButtonDown;
                }
                else
                {
                    (d as UIElement).PreviewMouseLeftButtonDown -= BlinkingWhenClickBehavior_PreviewMouseLeftButtonDown;
                }
            }
        
            static void BlinkingWhenClickBehavior_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                DoubleAnimation blink = new DoubleAnimation() { 
                                To = 1, 
                                From = 0, 
                                Duration = TimeSpan.FromMilliseconds(200) };
                (sender as UIElement).BeginAnimation(UIElement.OpacityProperty, blink);
            }
        }
        

        然后在您的 XAML 中,您可以将其附加到您的 image

        <Window x:Class="YourNameSpace.YourWindowClass"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:YourNameSpace"    
            <Button ...>
                <Image local:BlinkingBehaviour.IsBlinkingWhenClick="True"  .../>
            </Button>
        </Window>
        

        【讨论】:

        • 你为什么要限制这种行为只针对鼠标按下事件?加载操作完成后如何停止闪烁?
        • 我认为这就是 OP 想要的。不过不明白你的第二个问题,我将动画设置为点击后只运行一次。无论如何,OP找到了他喜欢的答案,我们可以继续前进..
        猜你喜欢
        • 2012-08-22
        • 2015-04-25
        • 2012-05-13
        • 2010-10-29
        • 1970-01-01
        • 2023-04-02
        • 2011-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多