MVVM Lightを使用していて、ダイアログを表示するために使用するインターフェイスIDialogServiceがあります。このインタフェースは、App.xaml.csに実装されているC#がGUIスレッドで待機して例外をキャッチWPF
一つの具体的な方法は興味深い:_currentTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
はOnStartup
public Task<bool> ShowMessage(string message, string title, string buttonConfirmText,
string buttonCancelText,
Action<bool> afterHideCallback)
{
return Task.Factory.StartNew(() =>
{
var style = new Style(typeof(MessageBox));
style.Setters.Add(new Setter(MessageBox.OkButtonContentProperty, buttonConfirmText));
style.Setters.Add(new Setter(MessageBox.CancelButtonContentProperty, buttonCancelText));
var result = MessageBox.Show(_GetActiveWindow(), message, title,
MessageBoxButton.OKCancel,
MessageBoxImage.Question, style) == MessageBoxResult.OK;
if (afterHideCallback != null) afterHideCallback(result);
return result;
:として
Task<bool> ShowMessage(string message, string title, string buttonConfirmText, string buttonCancelText, Action<bool> afterHideCallback);
方法が実装されています
通常、ブール値を取得するには、前に待ってこのメソッドを呼び出す必要があります。
var result = await DialogService.ShowMessage(
Resources.Areyousure,Resources.Warning,
Resources.Yes, Resources.No, null);
これまでのところとても良いです。今私はコードを実行し、例外をキャッチし、エラーメッセージ付きボックスを表示するラッパーメソッドがあります。
public bool TryCatchExecution(Action action, string successMessage = null)
{
try
{
action();
if (!string.IsNullOrEmpty(successMessage))
DialogService.ShowMessage(successMessage, Resources.Success);
return true;
}
catch (LogException ex)
{
DialogService.ShowError(ex.Error.LogMessage, Resources.Error, Resources.OK, null);
}
catch (Exception ex)
{
DialogService.ShowError(ex.Message, Resources.Error, Resources.OK, null);
}
return false;
}
これで問題が発生しました。サンプルAのように使用すると、GUIスレッドは行var result = DialogService.ShowMessage
でブロックされます。しかし、サンプルBのようにGUIスレッドがブロックされていない場合、メッセージボックスが表示され、すべてが正常に動作するように動作します。私が例外を得るまで。例外はコードによって手つかずです。エラーは、 "mscorlib.dllで 'System.ServiceModel.FaultException`1'型の最初のチャンス例外が発生し、アプリケーションがクラッシュします。私が読んでいるように、これにはSynchronizationContextと関連があります。
//Sample A
private void ExecuteDeleteCommand()
{
TryCatchExecution(() =>
{
var result = DialogService.ShowMessage(
Resources.Areyousure,
Resources.Warning,
Resources.Yes,
Resources.No, null).Result;
if (!result) return;
_datalayer.DeleteField(FieldSelected);
Refresh();
FieldEdit = new MsgSqlFieldMapping();
RaisePropertyChanged("SqlRepository");
DialogService.ShowMessage(Resources.OperationSucceeded, Resources.Success);
});
}
//Sample B
private void ExecuteDeleteCommand()
{
TryCatchExecution(async() =>
{
var result =await DialogService.ShowMessage(
Resources.Areyousure,
Resources.Warning,
Resources.Yes,
Resources.No, null);
if (!result) return;
_datalayer.DeleteField(FieldSelected);
Refresh();
FieldEdit = new MsgSqlFieldMapping();
RaisePropertyChanged("SqlRepository");
await DialogService.ShowMessage(Resources.OperationSucceeded, Resources.Success);
});
}
ここで起こっていることと対処方法を理解してください。
THNXたくさん。
私は.net4.5フレームワークを使用していますことを言及するのを忘れています。 – Gintaras