2

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;
}
Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393

4 Answers4

7

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();
}
Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
3

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!

Vijay Gill
  • 1,508
  • 1
  • 14
  • 16
  • Do you know to un-color when another control in the grouping is selected (trying to implement a highlight, going the C# route for now). – JulieC May 30 '14 at 21:25
  • Sorry for late reply. Try using Style.Triggers. Add one Trigger for the property IsFoused and value "true". Add setter to the trigger and set background to say Green. There is no need to un-colour as the trigger will also restore the original background when Isfocused becomes false. – Vijay Gill Jun 25 '14 at 15:57
0

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;
}
Cyril Gandon
  • 16,830
  • 14
  • 78
  • 122
0

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.

Community
  • 1
  • 1
Jodrell
  • 34,946
  • 5
  • 87
  • 124