Вы также можете создать интерфейс «виджетов» для выпадающего меню. Я приведу простой пример рабочего кода для виджета 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:
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 также является IViewWh независимо:
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 здесь) и в других технологиях пользовательского интерфейса по мере необходимости (если у вас есть интерфейс / базовый класс, реализация в другой технологии тривиальна). Это также легко проверить с помощью фиктивных объектов, потому что у вас есть интерфейс. И ваш пользовательский интерфейс теперь прекрасно знает практически все, кроме задач, связанных с пользовательским интерфейсом. Недостатком является набор классов для каждого виджета и небольшая кривая обучения, чтобы освоиться с ним.
Для вашего раскрывающегося списка вам может понадобиться событие типа SelectedIndexChanged, которое вы бы заменили для этого примера события TextChanged.