開発環境
- Windows 10 Home
- Microsoft Visual Studio Community 2019 Version 16.8.4
- Microsoft .NET Framework Version 4.8.03752
はじめに
最初に起動するスレッドとは別に、重たい処理を走らせるために非同期でタスクを立ち上げ、そのタスク内からUIを触る(例:editBox.Text = "test")と、例外エラーで落ちます。
今回は非同期処理中にUIを触れるようにする方法、ではなく
ユーザがUIに触れなくする方法について記します。
テキストボックスやボタンは、プロパティのEnabled属性をFalseに変更すればOKです。
ここでは、シート内のセルへのアクセスを無効化する方法について説明します。
対応前:非同期処理
Threadを使うのは古い方法みたいなので、async/awaitを利用します。
詳しい説明はコチラ
private async void func(...)
{
await System.Threading.Tasks.Task.Run(() =>
{
// 重たい処理
editBox.Text = "test"; // ※ここでUIを触ると例外エラー!
});
}
UI部品の無効化
UI変更時の見栄え改善と処理時間短縮のために描画の更新を停止します。
Globals.ThisAddIn.Application.ScreenUpdating = false;
リボン(Ribbon)内のUIコントロールを全部OFFするには下記のようにしますが、
foreach (RibbonGroup group in Globals.Ribbons.Ribbon1.tab_アドイン名.Groups)
{
foreach (RibbonControl ctrl in group.Items)
{
ctrl.Enabled = enable;
}
}
この対応では、シート内のセルにアクセスできてしまい、エラーが発生するので
代わりに、キーボードおよびマウスからの入力を止めます。
※ 確実にエラーハンドリングして、最後はtrueに戻してください。
Globals.ThisAddIn.Application.Interactive = false;
対応後のイメージ
private async void func(...)
{
Globals.ThisAddIn.Application.Interactive = false;
Globals.ThisAddIn.Application.ScreenUpdating = false;
await System.Threading.Tasks.Task.Run(() =>
{
// 重たい処理 ※ここでUIを触ると例外エラー!
Globals.ThisAddIn.Application.ScreenUpdating = true;
Globals.ThisAddIn.Application.Interactive = true;
});
}
以上です。