按代码刷新WPF-Control



我正在尝试禁用拒绝垃圾邮件的按钮。

我使用Refresh委托来Render调用控件,但它显示为已启用。如果按钮显示为已启用,则connect()-方法将花费大约4秒。

问题在哪里?

public static class ExtensionMethods
{
   private static Action EmptyDelegate = delegate() { };

   public static void Refresh(this UIElement uiElement)
   {
      uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
   }
}

private void buttonConnect_Click(object sender, RoutedEventArgs e)
{
    this.Cursor = Cursors.Wait;
    buttonConnect.IsEnabled = false;
    buttonConnect.Refresh();
    if (buttonConnect.Content.Equals("Connect"))
    {
        connect();
    }
    else
    {
        disconnect();
    }
    buttonConnect.IsEnabled = true;
    buttonConnect.Refresh();
    this.Cursor = Cursors.Arrow;
}

由于所有这些似乎都发生在UI- thread上,UI没有时间在其间更新,您需要在后台线程上运行任务并在完成时再次更改UI(例如使用已经有RunWorkerCompleted事件的BackgroundWorker)。

button.IsEnabled = false;
var bw = new BackgroundWorker();
bw.DoWork += (s, _) =>
{
    //Long-running things.
};
bw.RunWorkerCompleted += (s,_) => button.IsEnabled = true;
bw.RunWorkerAsync();

甚至更好,而不是乱搞事件,为什么不使用ICommand绑定,在那里你可以实现CanExecute,你可以返回true/false取决于你是否想要启用/禁用按钮

关于ICommand

的好例子

您正在将方法的优先级设置为Render,该方法实际上不做任何渲染。

我想说使用异步调用将是这里采取的最佳行动,给布局引擎时间来渲染:

private void buttonConnect_Click(object sender, RoutedEventArgs e)
{
    this.Cursor = Cursors.Wait; 
    buttonConnect.IsEnabled = false; 
    Action action = buttonConnect.Content.Equals("Connect") ? connect : disconnect;
    new Action(() => {
        action();
        Dispatcher.Invoke(() =>
            {
                buttonConnect.IsEnabled = true;
                this.Cursor = Cursors.Arrow;
            });
    }).BeginInvoke(null, null);
}

最新更新