按代码刷新WPF-Control

我试图禁用一个按钮,拒绝垃圾邮件点击此按钮。

我使用了一个Refresh委托来渲染调用控件,但它显示为已启用。 connect() – Methode大约需要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的一个很好的例子

您正在将方法的优先级设置为“渲染”,而实际上并不进行任何渲染。

我想说使用异步调用将是最好的操作,给布局引擎时间渲染:

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