简体   繁体   中英

How to change the background color of border after one second in WPF?

I click the button background of border is blue, after one second it should be red. It is red but not blue. Why?

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Border Width="111" Name="op" Height="111">
        <Button Name="opbtn" Click="opbtn_Click" Width="50" Height="23">click</Button>
    </Border>
</Window>

Code-behind:

private void opbtn_Click(object sender, RoutedEventArgs e)
{
    op.BorderBrush = System.Windows.Media.Brushes.Blue;
    DateTime obj1 = new DateTime(); 
    DateTime obj2 = DateTime.Now.AddMilliseconds(200);
    while (obj2 > obj1)
    {
        obj1 = DateTime.Now;
    }
    op.BorderBrush = System.Windows.Media.Brushes.Red;
}

Because you're tying up the UI thread with that loop. The UI thread never has a chance to apply your first change to the border brush because it's busy thrashing your CPU in that tight loop. You should use a DispatcherTimer or an animation to achieve this. Example of using DispatcherTimer :

private void opbtn_Click(object sender, RoutedEventArgs e)
{
    op.BorderBrush = System.Windows.Media.Brushes.Blue;

    var dispatcherTimer = new DispatcherTimer();
    dispatcherTimer.Interval = TimeSpan.FromSeconds(1);
    dispatcherTimer.Tick += delegate
    {
        op.BorderBrush = System.Windows.Media.Brushes.Red;
        dispatcherTimer.Stop();
    };

    dispatcherTimer.Start();
}

Why write code when WPF allows to similar thing in XAML itself. See the following example

<StackPanel Orientation="Horizontal" Height="24">
    <Border BorderThickness="2">
        <Border.BorderBrush>
            <SolidColorBrush x:Name="BorderBrush" />
        </Border.BorderBrush>
        <Button Content="Click me" Width="64" Height="24">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation To="Red"
                                        Duration="0:0:1" 
                                        Storyboard.TargetName="BorderBrush"
                                        Storyboard.TargetProperty="Color"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </Border>
</StackPanel>

You can modify it to suit your liking, make it part of resources so that it can be reused etc. All that without touching your code!

WPF doesn't refresh your layout immedialty after this line

op.BorderBrush = System.Windows.Media.Brushes.Blue;

Try to force the refresh layout with op.UpdateLayout() :

private void opbtn_Click(object sender, RoutedEventArgs e)
{
    op.BorderBrush = System.Windows.Media.Brushes.Blue;
    op.UpdateLayout();
    DateTime obj1 = new DateTime(); 
    DateTime obj2 = DateTime.Now.AddMilliseconds(200);
    while (obj2 > obj1)
    {
        obj1 = DateTime.Now;
    }
    op.BorderBrush = System.Windows.Media.Brushes.Red;
}

First, 200 miliseconds is fifth of a second, not 1 second.

The reason you see only red is because, when your code is finished, the border is red. Your code does not yield control before or during the loop so the blue does not get painted then.

If you want to animate the background colour of you control you will probably get much more satisfying results if follow the example in this answer Animated background control in WPF?

If you prefer the immediate colour change, then you there are several way to make that happen, as detailed by my fellow answerers. If you would like the smell to be especially piquant you could used the old System.Windows.Forms.Application.DoEvents , I believe this would still work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM