模型视图演示者和中继器

时间:2008-11-06 14:43:47

标签: repeater mvp supervisingcontroller

我正在使用监督控制器模式(模型视图演示者)构建应用程序,我遇到了困难。在我的页面中,我有一个转发器控件,它将显示我传递给它的一个系列的每个项目。 reapeater项目包含2个下拉列表,允许用户选择特定值。当我单击下一个按钮时,我希望控制器检索这些值。

我怎么能这样干净?

2 个答案:

答案 0 :(得分: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; }
    }
}

这在Form本身中实例化,返回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相关的任何事情。缺点是每个小部件的一堆类和一些学习曲线,以适应它。

对于您的下拉菜单,您可能只需要SelectedIndexChanged类型事件,您将替换此示例TextChanged事件。

答案 1 :(得分:1)

当控制器 - 视图交互过于复杂时,我通常将它们分成子控制器和子视图。

您可以让转发器中的项目成为具有自己的视图和控制器的用户控件。然后,您的主视图可以有一个子视图(usercontrols)列表,这些子视图具有由主控制器维护的自己的控制器。

当用户点击下一个时,您的主控制器可以通知所有子控制器从其视图中刷新其项目。