WPF属性未立即反映(仅反映最后一次更改)

时间:2014-12-29 23:22:28

标签: c# wpf properties

我想使用C#更改WPF按钮的颜色。

让我说我有一个WPF按钮,颜色我想改变一秒钟:

<Button Name="Button1"></Button>

我还有一个开始改变的按钮:

<Button Name="ProcessControl" Click="ProcessControl_Click">Start</Button>

我有C#代码,没有任何明显的变化:

private void ProcessControl_Click(object sender, RoutedEventArgs e)
{
        Brush background = button.Background;
        Button1.Background = System.Windows.Media.Brushes.Yellow;
        Thread.Sleep(1000);
        Button1.Background = background;
}

但是,如果我要编写这段代码,它会改变颜色,不会等待一秒钟而且它不会恢复旧的颜色,它会起作用:

private void ProcessControl_Click(object sender, RoutedEventArgs e)
{
        Brush background = button.Background;
        Button1.Background = System.Windows.Media.Brushes.Yellow;
}

所有WPF元素和属性都是一样的。如果某些属性更改了两次,则只会反映最后一次更改。

我也试过打电话:

this.UpdateLayout();

但它没有解决问题。

我尝试过使用后台工作程序,但它也无法解决我的问题。

现在有人如何使用C#立即反映WPF中的属性更改?

2 个答案:

答案 0 :(得分:2)

问题是您正在使用Sleep阻止UI线程,这意味着无法呈现更新的属性。如果您使用的是支持async / await的版本,则可以尝试使用:

private async void ProcessControl_Click(object sender, RoutedEventArgs e)
{
        Brush background = button.Background;
        Button1.Background = System.Windows.Media.Brushes.Yellow;
        await Task.Delay(1000);
        Button1.Background = background;
}

这会在UI线程上注册一个回调,在一秒钟之后触发(假设从UI线程调用Click事件处理程序,除非您手动调用该方法,否则它应始终是。)

答案 1 :(得分:0)

第一个代码示例无法正常工作,因为您使用Thread.Sleep阻止了UI线程。基本上,你(在UI线程上)

  1. 更改颜色
  2. 睡觉(注意用户界面还没有机会更新!)
  3. 改回颜色
  4. UI更新,旧颜色!
  5. 如果你改变颜色,那么在后台工作者上执行此操作可以工作,然后在另一个线程上睡眠第二次更改。当然,这个改变必须被整理回UI线程,所以如果你不小心放置Sleep,你会看到相同的行为。

    实际上,你应该只改变颜色,然后设置一个计时器。在该计时器的Elapsed事件中,将颜色设置回来。您也可以使用async / await,这样UI线程就不会阻塞,就像Dan Bryant的回答一样。