このコードの問題は、doSomeThing()
メソッドがUIスレッドで実行されていることです。したがって、ボタンは正しく無効になっていません。 doSomeThing()
メソッドが別のスレッドで実行されるようにコードをリファクタリングすると、正常に動作します。以下は、BackgroundWorker
を使用した簡単な例です。しかし、私たちはUIスレッドで時間のかかるものを実行すべきではないという考えです。ここで、リファクタリング、コードは次のとおりです。
public partial class ButtonEnableTest : Window
{
private BackgroundWorker worker = new BackgroundWorker();
public ButtonEnableTest()
{
InitializeComponent();
this.worker.DoWork += new DoWorkEventHandler(worker_DoWork);
this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (this.btn.IsEnabled == false)
{
this.btn.IsEnabled = true;
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
doSomeThing();
}
private void doSomeThing()
{
int i = 5;
while (i > 0)
{
Thread.Sleep(TimeSpan.FromMilliseconds(2000));
System.Diagnostics.Debug.WriteLine("Woke up " + i);
i--;
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button) sender;
System.Diagnostics.Debug.WriteLine("at ButtonClick");
if (btn.IsEnabled)
{
btn.IsEnabled = false;
this.worker.RunWorkerAsync();
}
}
}
私はちょうど私の考えを共有したいと思って、私はここで任意のコード変換に従っていませんでした。私はWPFボタンを "btn"と命名しました。
ボタンをクリックすると、実際にボタンが無効な視覚的な外観に変わりますか?そうでない場合は、あなたの質問はおそらく[この質問](http://stackoverflow.com/questions/9519295/updatelayout-on-wpf-click/9519860#9519860)と似ています – ianschol
はい、視覚的な外観を無効に変更します – HelloWorld