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

C# WPF属性未立即反映(仅反映最后一次更改),c#,wpf,properties,C#,Wpf,Properties,我想用C#更改WPF按钮的颜色 假设我有一个WPF按钮,我想在1秒内改变它的颜色: <Button Name="Button1"></Button> 但是,如果我要编写这段代码,它会改变颜色,不会等待一秒钟,也不会恢复旧的颜色,它可以工作: private void ProcessControl_Click(object sender, RoutedEventArgs e) { Brush background = button.Background;

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

假设我有一个WPF按钮,我想在1秒内改变它的颜色:

<Button Name="Button1"></Button>
但是,如果我要编写这段代码,它会改变颜色,不会等待一秒钟,也不会恢复旧的颜色,它可以工作:

private void ProcessControl_Click(object sender, RoutedEventArgs e)
{
        Brush background = button.Background;
        Button1.Background = System.Windows.Media.Brushes.Yellow;
}
所有WPF元素和属性都是一样的。如果某些属性更改了两次,则只会反映最后一次更改

我还试着打电话给:

this.UpdateLayout();
但这并不能解决问题

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


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

问题是您正在使用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事件处理程序,除非手动调用该方法,否则它应该始终是这样。)

第一个代码示例将不起作用,因为您使用
thread.Sleep
阻止UI线程。基本上,您(在UI线程上)

  • 换颜色
  • 睡眠(注意UI还没有机会更新!)
  • 把颜色改回去
  • 用户界面更新,以旧的颜色 如果您更改了颜色,然后在另一个线程上执行第二次更改,那么在后台工作人员上执行此操作可能会起作用。当然,该更改必须被封送回UI线程,因此如果在放置
    Sleep
    时不小心,您将看到相同的行为


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

    很可能是您的
    线程。Sleep(1000)
    正在阻塞UI线程,因此按钮不会被重新绘制为新颜色。您可能应该使用动画来执行此操作,而不是使用
    wait
    ,这样做感觉非常错误。它当然有效;回答得好@BradleyDotNET,我喜欢使用
    Task.Delay
    作为在UI线程上注册计时器回调的简写版本;我现在几乎总是用它来代替显式计时器。诚然,拥有一个异步void方法并不是一个很好的实践;当您将上述模式推广到生产代码中时,您一定要注意可能会在延迟期内更改应用程序状态的“如果”情况(当您睡眠UI线程时,通常会抑制这种情况)。计时器回调也有这些问题,尽管等待可能不太明显。
    this.UpdateLayout();
    
    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;
    }