これまで例外の話をしてきていますが,引き続き例外の話をします。
メッセージボックスのアイコン
Searchボタンクリックイベント例外になったときに,メッセージを出していますが,メッセージだけでなく,インフォメーション,警告,エラー,などの区分に応じたアイコンを出すことができます。ユーザーの見た目にもわかりやすくなるので,出したほうがいいでしょう。
例外のレベル
アイコンのレベルなどは,例外にレベルを付けておくと,画面で表示するメッセージのアイコンなどの表示に利用できます。つまり,インフォメーション,警告,エラーなどに分けておくことで,画面にて,どのようなアイコン表示をするかを判断できます。
ExceptionBaseの作成
ドメインのExceptionsフォルダーにExceptionBaseクラスを新規で作成します。
ExceptionBaseの実装
using System; namespace NDDD.Domain.Exceptions { public abstract class ExceptionBase : Exception { public ExceptionBase(string message) : base(message) { } public ExceptionBase(string message, Exception exception) : base(message, exception) { } public abstract ExceptionKind Kind { get; } public enum ExceptionKind { Info, Warning, Error, } } }
ExceptioinBaseは抽象クラスのため,abstractとしています。ExceptionKindがエラーの区分です。public abstract ExceptionKind Kind{get;}の部分で,サブクラスに例外区分の実装を強制しています。つまりExceptioinBaseを継承すると,例外区分を実装しないとコンパイルが通らないという事です。これで,自作するすべての例外をExceptioinBaseを継承するようにしておくことで,すべての自作例外に例外区分が実装されるという事が保証されます。
ExceptionBaseを継承する
これまで作成した,FakeExceptionとDataNotExistsExeptionでExceptioinBaseを継承するように変更します。Kindの実装を強制されるので,それぞれ次のように実装しておきます。
using System; namespace NDDD.Domain.Exceptions { public sealed class FakeException : ExceptionBase { public FakeException(string message, Exception exception) : base(message, exception) { } public override ExceptionKind Kind => ExceptionKind.Error; } }
ExceptionKindの返却を強制される
namespace NDDD.Domain.Exceptions { public sealed class DataNotExistsExeption : ExceptionBase { public DataNotExistsExeption() :base("データがありません") { } public override ExceptionKind Kind => ExceptionKind.Info; } }
画面側で判断する
LatestViewのcatchしている部分で,例外をExceptioinBaseに変換し,アイコンなどを設定してメッセージを表示します。
using NDDD.Domain.Exceptions; using NDDD.WinForm.ViewModels; using System; using System.Windows.Forms; namespace NDDD.WinForm.Views { public partial class LatestView : BaseForm { private LatestViewModel _viewModel = new LatestViewModel(); public LatestView() { InitializeComponent(); AreaIdTextBox.DataBindings.Add( "Text", _viewModel, nameof(_viewModel.AreaIdText)); MeasureDateTextBox.DataBindings.Add( "Text", _viewModel, nameof(_viewModel.MeasureDateText)); MeasureValueTextBox.DataBindings.Add( "Text", _viewModel, nameof(_viewModel.MeasureValueText)); } private void SearchButton_Click(object sender, System.EventArgs e) { try { _viewModel.Search(); } catch(Exception ex) { MessageBoxIcon icon = MessageBoxIcon.Error; string caption = "エラー"; var exceptionBase = ex as ExceptionBase; if (exceptionBase != null) { if (exceptionBase.Kind == ExceptionBase.ExceptionKind.Info) { icon = MessageBoxIcon.Information; caption = "情報"; } else if (exceptionBase.Kind == ExceptionBase.ExceptionKind.Warning) { icon = MessageBoxIcon.Warning; caption = "警告"; } } MessageBox.Show(ex.Message, caption, MessageBoxButtons.OK, icon); } } } }
ExceptioinBaseに変換できない場合は,そのままエラーとなり,ExceptioinBaseに変換できた場合はKindに従って,アイコンなどを調整しています。