2011-08-11 30 views
0

我点击边框的按钮背景是蓝色的,一秒后它应该是红色的。它是红色但不是蓝色。为什么?如何在WPF中改变边界的背景颜色?

<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> 

代码隐藏:

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; 
} 

回答

4

因为你占用与循环UI线程。 UI线程从来没有机会将第一次更改应用到边界刷,因为它正在忙于在紧密的循环中颠簸CPU。您应该使用DispatcherTimer或动画来实现此目的。使用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(); 
} 
0

WPF不刷新你的布局immedialty此行之后

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

尝试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; 
} 
0

首先,200毫秒是第二秒,而不是1秒。

你只看到红色的原因是因为当你的代码完成时,边框是红色的。您的代码在循环之前或循环中不会产生控制,因此蓝色不会被绘制。

如果你想要的,你控制,你可能会得到更令人满意的结果,如果按照这个答案的例子,以动画的背景色Animated background control in WPF?

如果你喜欢的颜色立即改变,那么你有几种办法做到这一点,就像我的同事回答的那样。如果你想让气味特别辛辣,你可以使用旧的System.Windows.Forms.Application.DoEvents,我相信这仍然会奏效。

1

为什么在WPF允许XAML本身类似的事情时编写代码。请看下面的例子

<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> 

您可以修改它来满足自己的喜好,使其资源的一部分,这样可以重复使用等,所有这一切不碰你的代码!

+0

如果选择了分组中的其他控件(试图实现高亮,现在转到C#路线),您是否知道取消颜色? – JulieC

+0

对不起,延迟回复。尝试使用Style.Triggers。为属性IsFoused添加一个触发器并且值“true”。将setter添加到触发器并将背景设置为绿色。当Isfocused变为false时,不需要取消颜色,因为触发器也会恢复原始背景。 –