モデルビューのプレゼンターとリピーター
-
06-07-2019 - |
質問
Supervising Controllerパターン(Model View Presenter)を使用してアプリケーションを構築していますが、困難に直面しています。私のページには、渡すコレクションの各アイテムを表示するリピーターコントロールがあります。 reapeaterアイテムには、ユーザーが特定の値を選択できる2つのドロップダウンリストが含まれています。次のボタンをクリックすると、コントローラーにこれらの値を取得させます。
どのようにすればきれいにできますか?
解決
ドロップダウン用の「ウィジェット」インターフェースを作成することもできます。 TextBoxウィジェットのいくつかの実用的なコードの簡単な例を挙げて、アイデアを理解してください。
public interface ITextWidget
{
event EventHandler TextChanged;
string Text { get; set; }
}
public abstract class TextWidget<T> : ITextWidget
{
protected T _wrappedWidget { get; set; }
public event EventHandler TextChanged;
protected void InvokeTextChanged(object sender, EventArgs e)
{
var textChanged = TextChanged;
if (textChanged != null) textChanged(this, e);
}
public abstract string Text { get; set; }
}
これまでのところ、すべてがテクノロジーに依存しないことに注意してください。次に、Win Forms TextBoxの実装を示します。
public class TextBoxWidget : TextWidget<TextBox>
{
public TextBoxWidget(TextBox textBox)
{
textBox.TextChanged += InvokeTextChanged;
_wrappedWidget = textBox;
}
public override string Text
{
get { return _wrappedWidget.Text; }
set { _wrappedWidget.Text = value; }
}
}
これはフォーム自体でインスタンス化され、MVPに戻るのはIViewWhateverでもあります:
public partial class ProjectPickerForm : Form, IProjectPickerView
{
private IProjectPickerPresenter _presenter;
public void InitializePresenter(IProjectPickerPresenter presenter) {
_presenter = presenter;
_presenter.InitializeWidgets(
...
new TextBoxWidget(txtDescription));
}
...
}
そしてプレゼンター:
public class ProjectPickerPresenter : IProjectPickerPresenter
{
...
public void InitializeWidgets(ITextWidget descriptionFilter) {
Check.RequireNotNull<ITextWidget>(descriptionFilter, "descriptionFilter");
DescriptionFilter = descriptionFilter;
DescriptionFilter.Text = string.Empty;
DescriptionFilter.TextChanged += OnDescriptionTextChanged;
}
...
public void OnDescriptionTextChanged(object sender, EventArgs e) {
FilterService.DescriptionFilterValue = DescriptionFilter.Text;
}
アイデアを得ると、ほとんどの作業はかなり機械的なものになるため、セットアップするよりも悪く見えます。きれいな部分は、プレゼンターが、実際に実装されたウィジェットが何であるかを知らず、気にせずに、ウィジェットで必要な情報を取得(および設定)できることです。また、同じタイプ(ここではWin Forms)の他のウィジェット(それらのライブラリを構築することになります)および必要に応じて他のUIテクノロジーで再利用するのに役立ちます(インターフェース/基本クラスがあれば、別のテクノロジーでの実装はつまらない)。また、インターフェイスがあるため、モックオブジェクトで簡単にテストできます。そして、UIは、UI関連のタスク以外のほとんどすべてについて驚くほど無知になりました。欠点は、ウィジェットごとのクラスの束とそれに慣れるための小さな学習曲線です。
ドロップダウンには、この例のTextChangedイベントの代わりに使用するSelectedIndexChangedタイプのイベントが必要な場合があります。
他のヒント
コントローラーとビューの相互作用が複雑すぎる場合、私はそれらをサブコントローラーとサブビューに分割します。
リピーターのアイテムを、独自のビューとコントローラーを持つユーザーコントロールにすることができます。メインビューには、メインコントローラーによって管理される独自のコントローラーを持つサブビュー(ユーザーコントロール)のリストを含めることができます。
ユーザーが次にクリックすると、メインコントローラーはすべてのサブコントローラーに信号を送り、ビューからアイテムを更新します。