none
UWP 請問如何讓圖形顏色閃爍變換? RRS feed

  • 問題

  • 我原本以為要讓UI圖形顏色做閃爍是很簡單的事﹐不是就直接更換顏色就好了嗎?
            private void ShineLight1() {
                for (int i = 0; i < 3; i++) {
                    ellipseLight.Fill = new SolidColorBrush(Colors.Red);
                    Task.Delay(500).Wait();
                    ellipseLight.Fill = new SolidColorBrush(Colors.Green);
                    Task.Delay(500).Wait();
                }
            }

    但實做之後發現不是這麼回事﹐在方法執行過程中UI並不會跟著一起變化﹐上網研究了一下以為設定了 Binding Mode 為 OneWay 搭配delegate應該就可以了﹐可是天不從人願....﹐請問應該怎麼做才能做出顏色變換閃爍的效果呢?

            <Ellipse x:Name="ellipseLight" Fill="{x:Bind newColor,Mode=OneWay}" HorizontalAlignment="Left" Height="200" Margin="158,89,0,0" VerticalAlignment="Top" Width="200" />
            <Button x:Name="btnShine" Content="閃爍" HorizontalAlignment="Left" Margin="557,317,0,0" VerticalAlignment="Top" FontSize="36" Width="140" Height="60" Click="btnShine_Click"/>

    namespace ShineLightApp {
        public sealed partial class MainPage : Page, INotifyPropertyChanged {
    
            private Brush _newColor;
    
            public Brush newColor {
                get { return _newColor; }
                set {
                    if (_newColor != value) {
                        _newColor = value;
                        RaisePropertyChanged("newColor");
                    }
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public MainPage() {
                this.InitializeComponent();
            }
    
            private void btnGreen_Click(object sender, RoutedEventArgs e) {
                ellipseLight.Fill = new SolidColorBrush(Colors.Green);
            }
    
            private void btnShine_Click(object sender, RoutedEventArgs e) {
                //ShineLight1();
                ShineLight2();
            }
    
            private void ShineLight1() {
                for (int i = 0; i < 3; i++) {
                    ellipseLight.Fill = new SolidColorBrush(Colors.Red);
                    Task.Delay(500).Wait();
                    ellipseLight.Fill = new SolidColorBrush(Colors.Green);
                    Task.Delay(500).Wait();
                }
            }
    
            public delegate void SwitchColorDelegate(Color mycolor);
    
            private void mySwitchColor(Color color) {
                ellipseLight.Fill = new SolidColorBrush(color);
            }
            private void ShineLight2() {
                SwitchColorDelegate ellipseColor = new SwitchColorDelegate(mySwitchColor);
    
                for (int i = 0; i < 3; i++) {
                    //newColor = new SolidColorBrush(Colors.Red);
                    //this.Bindings.Update();
                    ellipseColor.Invoke(Colors.Red);
                    Task.Delay(500).Wait();
    
                    //newColor = new SolidColorBrush(Colors.Green);
                    //this.Bindings.Update();
                    ellipseColor.Invoke(Colors.Green);
                    Task.Delay(500).Wait();
                }
            }
    
    
            private void RaisePropertyChanged(string propertyName) {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }



    2018年2月17日 上午 02:44

解答

  • 在 UWP, WPF 這類XAML base 的程式裡, 這種效果要使用 "動畫" 來完成。

    以下範例示範兩種不同的效果, 一個是 "閃爍", 一個是 "連續顏色轉換"

    <Page
        x:Class="App1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.Resources >
            <Storyboard x:Name="fadeStoryboard">
                <ColorAnimationUsingKeyFrames 
                    Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" 
                    Storyboard.TargetName="ellipse" AutoReverse="True" RepeatBehavior="Forever">
                    <EasingColorKeyFrame KeyTime="0:0:0.5" Value="Red" />
                </ColorAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Name="blinkStoryboard">
                <ObjectAnimationUsingKeyFrames
                 Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                 Storyboard.TargetName="ellipse" AutoReverse="True" RepeatBehavior="Forever">               
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="Red"/>
                    <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="Green"/>
                </ObjectAnimationUsingKeyFrames> 
            </Storyboard>
        </Page.Resources>
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions >
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Button Grid.Row="0" Margin="12" Content="閃爍" Click="Button_Click" />
            <Button Grid.Row="1" Margin="12" Content="連續轉換" Click="Button1_Click" />
            <Ellipse Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center"
                     Width="160" Height="160" Fill="Green" x:Name="ellipse"/>
        </Grid>
    </Page>
    

       public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                fadeStoryboard.Stop();
                blinkStoryboard.Begin(); 
            }
    
            private void Button1_Click(object sender, RoutedEventArgs e)
            {
                blinkStoryboard.Stop(); 
                fadeStoryboard.Begin(); 
            }
        }
    進一步的內容可參考  Animations in XAML

     

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2018年2月17日 上午 04:09
    版主
  • 可以利用 repeatbehavior 來決定閃爍的次數。

    這樣的需求用甚麼 Timer, Task Delay 都很難做出好效果, 一定是靠動畫來做才是王道。

    例如你可以這樣改

     private void Button_Click(object sender, RoutedEventArgs e)
            {
                fadeStoryboard.Stop();
                blinkStoryboard.RepeatBehavior = new RepeatBehavior(3);
                blinkStoryboard.Begin(); 
            }
    就會閃爍三次


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2018年2月18日 上午 10:27
    版主

所有回覆

  • 在 UWP, WPF 這類XAML base 的程式裡, 這種效果要使用 "動畫" 來完成。

    以下範例示範兩種不同的效果, 一個是 "閃爍", 一個是 "連續顏色轉換"

    <Page
        x:Class="App1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.Resources >
            <Storyboard x:Name="fadeStoryboard">
                <ColorAnimationUsingKeyFrames 
                    Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" 
                    Storyboard.TargetName="ellipse" AutoReverse="True" RepeatBehavior="Forever">
                    <EasingColorKeyFrame KeyTime="0:0:0.5" Value="Red" />
                </ColorAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Name="blinkStoryboard">
                <ObjectAnimationUsingKeyFrames
                 Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                 Storyboard.TargetName="ellipse" AutoReverse="True" RepeatBehavior="Forever">               
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="Red"/>
                    <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="Green"/>
                </ObjectAnimationUsingKeyFrames> 
            </Storyboard>
        </Page.Resources>
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions >
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Button Grid.Row="0" Margin="12" Content="閃爍" Click="Button_Click" />
            <Button Grid.Row="1" Margin="12" Content="連續轉換" Click="Button1_Click" />
            <Ellipse Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center"
                     Width="160" Height="160" Fill="Green" x:Name="ellipse"/>
        </Grid>
    </Page>
    

       public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                fadeStoryboard.Stop();
                blinkStoryboard.Begin(); 
            }
    
            private void Button1_Click(object sender, RoutedEventArgs e)
            {
                blinkStoryboard.Stop(); 
                fadeStoryboard.Begin(); 
            }
        }
    進一步的內容可參考  Animations in XAML

     

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2018年2月17日 上午 04:09
    版主
  • Bill 大﹐我想做的效果是我給一個數值﹐然後根據這個值閃爍次數﹐動畫的方式看來是設定頻率﹐我另外參考了網路上的方式改用Timer﹐但都不是我想要的方式。

    嚴格來說根劇設定的值計算頻率來逹到閃爍次數也不是不行﹐只是不知道還有沒有其它比較直覺的方式。


    2018年2月18日 上午 07:40
  • 可以利用 repeatbehavior 來決定閃爍的次數。

    這樣的需求用甚麼 Timer, Task Delay 都很難做出好效果, 一定是靠動畫來做才是王道。

    例如你可以這樣改

     private void Button_Click(object sender, RoutedEventArgs e)
            {
                fadeStoryboard.Stop();
                blinkStoryboard.RepeatBehavior = new RepeatBehavior(3);
                blinkStoryboard.Begin(); 
            }
    就會閃爍三次


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2018年2月18日 上午 10:27
    版主
  • Bill 大﹐你的王道做法太棒了﹐效果非常好~~感謝。
    2018年2月18日 下午 05:19