【问题标题】:How to properly disable buttons temporarily in a WPF application?如何在 WPF 应用程序中临时正确禁用按钮?
【发布时间】:2016-10-31 12:07:11
【问题描述】:

我对 WPF 相当陌生,并且仍在寻找一种简单的解决方案来暂时停用我的应用程序中的按钮。这是我正在做的事情:

按钮点击:

private void Calculate_Click(object sender, RoutedEventArgs e)
    {
      this.AreButtonsEnabled = false;
      System.Threading.Thread.Sleep(1000);
      this.AreButtonsEnabled = true;      
    }

XAML:

<Button x:Name="OtherButton" IsEnabled="{Binding AreButtonsEnabled}" Content="OtherButton" HorizontalAlignment="Left" Margin="165,152,0,0" VerticalAlignment="Top" Width="75"/>

绑定按预期工作,但如果我激活和停用此调用中的按钮,则停用不会完成。如何让 GUI 正确停用按钮?

编辑

通知事件(工作正常):

public partial class MainWindow : Window, INotifyPropertyChanged
  {

    private bool areButtonsEnabled;
    public bool AreButtonsEnabled
    {
      get { return this.areButtonsEnabled; }
      set { areButtonsEnabled = value; OnPropertyChanged(new PropertyChangedEventArgs("AreButtonsEnabled")); }
    }

注意 我必须使用 .Net 3.5。

【问题讨论】:

  • 你能发布你的“AreButtonsEnabled”属性是如何声明的吗?
  • 这可能是因为 UI 在休眠之前没有时间对 AreButtonsEnabled 设置为 false 做出反应。
  • 我建议使用 ICommand 接口和 RelayCommand 等基本实现

标签: c# wpf xaml


【解决方案1】:

最好禁用按钮,然后启动/使用另一个线程来完成工作并在最后启用按钮(一种方法是使用异步/等待),这样 UI 将保持负责并保持最新状态。

伪代码:

private async void Calculate_Click(object sender, RoutedEventArgs e)
{
    AreButtonsEnabled = false;
    await Task.Run(()=>DoWork());
    AreButtonsEnabled = true;      
}

【讨论】:

  • StartNew is Dangerous。最好使用Task.Run()
  • 对不起,我忘了说我绑定了net framework 3.5。但我明白了。我认为开始一项新任务是一种选择,尤其是对于耗时的任务。但是我认为可能有一个任务解决方案,但没有那么广泛,用户可以接受被阻止的 gui(时间跨度 1 - 2 秒)?
  • @Kroetenwurz - 微软认为任何阻塞 UI 超过 50 毫秒的东西都是“坏的”。此外,您的方案确实需要更新 UI(这是您最初的问题),同时代码要求 UI 线程来完成工作。
  • 好吧,你说服了我。感谢您的回答和意见,包括 Erno 和 Clemens 以及其他人。我会让在非 UI 线程中执行所有任务。
【解决方案2】:

Thread.Sleep() 阻塞 UI 线程。您可以使用 async 点击处理程序和 Task.Delay() 来代替:

private async void Calculate_Click(object sender, RoutedEventArgs e)
{
    AreButtonsEnabled = false;
    await Task.Delay(1000);
    AreButtonsEnabled = true;      
}

【讨论】:

  • 对不起,我忘了说我绑定了net framework 3.5。但我明白了。我可以在进入任务(睡眠)之前强制 GUI 更新吗?
  • 您不得在 UI 中调用 Thread.Sleep。绝不。相反,您可能有一些异步操作,例如在BackgroundWorker.
  • 嘿克莱门斯。睡眠是只需要一两秒的任务的占位符。足以让用户按下另一个按钮,这是我想阻止的
猜你喜欢
  • 2019-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 1970-01-01
  • 2018-11-04
相关资源
最近更新 更多