我正在C#中开发Winforms应用程序。我在GUI编程方面的经验有限,我必须即时学习很多东西。话虽这么说,这就是我正在建立的。

请参阅GUI查看以下链接:

GUI http://img227.imageshack.us/img227/1084/program0.jpg

现在,我已经完成了很多工作,但是以非常糟糕的自主设计模式。我不知道该项目会达到一定的规模,因此,是时候做一些重大的重构了。

我一直在研究有关GUI设计模式的大量知识,我希望实施的模式是被动视图(请参阅 http://martinfowler.com/eaadev/passivescreen.html)。我正在寻找有关如何将所有这些结合在一起的帮助。

背景:

1)根据用户在“ TreeView”中单击的内容,左下角的“列表”将显示可以填充“编辑器”区域的对象列表。这些对象可能是文本框或datagridView。用户切换列表以选择他/她想在“编辑器”中看到的内容

2)该模型本质上是带有数据和配置文件的文件夹。有一个外部程序在给定目录上运行,创建输出文件/文件夹等。我正在开发的此程序旨在以用户友好的方式有效地管理/配置这些对象

3)我一直在做事的问题是,它几乎无法测试,因此转移到MVP式的被动视图设计模式

我正在尝试做到这一点,以便该程序独立于视图。我找不到任何示例,这些示例与被动视图模式一起使用了更复杂,更复杂的交互式视图。

问题:

1)我是否需要为程序的整个“外观”实现一个大型接口/视图,然后为每个TreeView,Editor,Logger等实现子接口/子视图?还是这样做有更好的“结构”?

2)当涉及到从视图到主持人/控制器的“交出”事件(无论您希望使用WRT的被动视图设计模式如何)时,我应该做什么?有时,我有需要更新的简单属性,有时我需要一系列步骤才能展开。

我希望就此主题提出建议和建议。我已经搜寻了互联网,但我还没有找到足够的例子来帮助我继续这个项目。

提前致谢!

丹尼尔

有帮助吗?

解决方案

这是一个简单的示例,它使用MVP设计模式演示了被动视图的概念。因为我们使用的是被动观点,所以观点不了解主持人。主持人将简单地订阅观点发布的事件并采取相应的行动。

首先,我们需要为我们的观点定义合同。从本质上讲,这通常是使用界面来实现的,我们希望与我们的视图结合起来。我们希望能够切换到不同的视图或事件创建模拟视图以进行单元测试。

这是一份合同,描述了一个简单的视图,该视图将用于显示客户信息

public interface ICustomerManagementView
{
    void InitializeCustomers(ICustomer[] customers);
    void DisplayCustomer(ICustomer customer);
    event EventHandler<EventArgs<ICustomer>> SelectedCustomerChanged;
}

它暴露了一种方法 初始Zecustomers 这将用于用模型中的对象初始化我们的视图。

我们也有一个活动 选择的customerchanged 我们的演示者将使用该通知,以收到有关在视图中发生的诉讼的通知。

一旦获得合同,我们就可以开始在主持人中处理这些互动。

public class CustomerManagementPresenter
{
    private ICustomer _selectedCustomer;
    private readonly ICustomerManagementView _managementView;
    private readonly ICustomerRepository _customerRepository;

    public CustomerManagementPresenter(ICustomerManagementView managementView, ICustomerRepository customerRepository)
    {
        _managementView = managementView;
        _managementView.SelectedCustomerChanged += this.SelectedCustomerChanged;

        _customerRepository = customerRepository;

        _managementView.InitializeCustomers(_customerRepository.FetchCustomers());
    }

    private void SelectedCustomerChanged(object sender, EventArgs<ICustomer> args)
    {
        // Perform some logic here to update the view
        if(_selectedCustomer != args.Value)
        {
            _selectedCustomer = args.Value;
            _managementView.DisplayCustomer(_selectedCustomer);
        }
    }
}

在主持人中,我们可以使用另一种名为的设计模式 依赖注射 提供对我们的视图和我们可能需要的任何模型类的访问。在此示例中,我有一个客户介绍,负责获取客户详细信息。

在构造函数中,我们有两条重要的代码行,首先,我们在视图的视图中订阅了SelectedCustomerchanged事件,我们可以在这里执行关联的操作。其次,我们将来自存储库的数据称为Initilaizecustomers。

在这一点上,我们实际上还没有为我们的观点定义具体实现,我们需要做的就是创建一个实现的对象 ICUSTOMERMANGAIMENTVIEW. 。例如,在Windows表单应用程序中,我们可以执行以下操作

public partial class CustomerManagementView : Form, ICustomerManagementView
{
    public CustomerManagementView()
    {
        this.InitializeComponents();
    }

    public void InitializeCustomers(ICustomer[] customers)
    {
        // Populate the tree view with customer details
    }

    public void DisplayCustomer(ICustomer customer)
    {
        // Display the customer...
    }

    // Event handler that responds to node selection
    private void CustomerTreeViewAfterSelect(object sender, TreeViewEventArgs e)
    {
        var customer = e.Node.Tag as ICustomer;
        if(customer != null)
        {
            this.OnSelectedCustomerChanged(new EventArgs<ICustomer>(customer));
        }
    }

    // Protected method so that we can raise our event
    protected virtual void OnSelectedCustomerChanged(EventArgs<ICustomer> args)
    {
        var eventHandler = this.SelectedCustomerChanged;
        if(eventHandler != null)
        {
            eventHandler.Invoke(this, args);
        }
    }

    // Our view will raise an event each time the selected customer changes
    public event EventHandler<EventArgs<ICustomer>> SelectedCustomerChanged;
}

如果我们想测试演示逻辑,我们可以嘲笑我们的观点并执行一些断言。

编辑:包括自定义事件args

public class EventArgs<T> : EventArgs
{
    private readonly T _value;

    public EventArgs(T value)
    {
        _value = value;
    }

    public T Value
    {
        get { return _value; }
    }
}

其他提示

我会用自己的礼物将它们分解为单独的视图,并使用“控制”演示者 /视图来管理所有人之间的消息委托。这种不仅可以帮助可检验性,而且还可以使您的控制能够满足SRP。

因此,在您的情况下,您可能会有一个IFORMMANAGER,主窗口将实现,然后是IfileManager,IloggerWindow等。

尽管使用可能有点过分杀伤,但我建议您查看智能客户端软件工厂(来自Microsoft模式和实践团队) - 它不再积极开发,但它具有MVP和MVP和这种视图构图的内容是否很好,因此可能会给您一些好主意。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top