【问题标题】:Should code be inside user control or the form using it代码应该在用户控件内还是在使用它的表单内
【发布时间】:2016-02-18 06:53:53
【问题描述】:

我有一个小的设计问题,由于某种原因我找不到相关的谷歌点击。

我有一个在我的应用程序中使用的用户控件。 主窗体打开第二个窗体作为对话框。吨 他的第二种形式是使用包含列表框的用户控件。

当然,我想在表单处理时保留列表框项,因此我在主表单中保留了一个私人列表。

List<string> _listofFirstCoordinates = new List<string>();

现在的问题是,对话框表单应该负责将列表中继到主表单还是代码应该在用户控件中?

填充列表的应该是用户控件

lst_Coordinates.Items.AddRange(ListOfCoordinates.Cast<object>().ToArray());

或者使用它的表单应该填充它(子表单)

uc_EditCoordinates.ListOfCoordinates = ListOfCoordinates;

还可以让用户控件成为持有它的表单的公共变量,以便可以直接更改它还是设计不好?

编辑: 顺便说一句,数据现在保存在表单之间来回的变量中,因为用户必须在提交之前完成所有子表单并最终将其保存到数据库中。所以这是一个

var _listofFirstCoordinates = new List<string>();

来回走动。

【问题讨论】:

标签: c# winforms


【解决方案1】:

“正确”的解决方案是从控制器和模型级别的问题(在在这种情况下,您的应用程序的数据)。

无需完全重新架构您的系统,您仍然可以在您的示例中应用这种关注点分离。

您可以在概念上争论 MainForm 类的“代码隐藏”充当一种控制器(纯粹主义者不同意)。它必须知道如何创建子窗体,但它不需要知道子窗体中托管的用户控件 - 这将是子窗体的关注点。

我建议定义一个代表 ViewModel 的类 - 尽管我们使用的是 WinForms,但我们会将其用作一种粗略的“单向”ViewModel,如下所示:

class MainForm : Form {

    private void ShowChildFormModal() {

        ChildViewModel vm = new ChildViewModel();
        vm.CoordinatesList = ...
        vm.OtherData = ...

        ChildForm child = new ChildForm();
        child.LoadFromViewModel( vm );
        child.ShowDialog();
        child.SaveToViewModel( vm );

        SaveToDatabase( vm );
    }
}

class ChildViewModel { // this is a POCO
    public List<String> CoordinatesList;
    public Int32 OtherData;
}

class ChildForm : Form {

    public void LoadFromViewModel(ChildViewModel vm) {

        // save time and trouble by using the List as a datasource directly, or you can manually populate the combobox as well
        this.childUserControl.LoadFromViewModel( vm ); 

        this.someOtherControl.Value = vm.OtherData;
    }

    public void SaveToViewModel(ChildViewModel vm) {
        // completing this is an exercise for the reader
        // but basically copy values from the controls on the form into the `vm` instance
    }
}

class ChildUserControl : UserControl {

    public void LoadFromViewModel(ChildViewModel vm) {
        this.comboBox.DataSource = vm.CoordinatesList;
    }
}

【讨论】:

  • 我应该补充一点,因为数据现在保存在表单之间来回切换的变量中,因为用户必须在提交之前完成所有子表单并最终将其保存到数据库中。所以它是一个 var _listofFirstCoordinates = new List();来回走动。这会改变您的回复吗?
  • @AngelicCore ViewModel 模式仍然适用,实际上它会让您的工作更轻松,因为单个 ViewModel 实例可以表示整个表单集合的状态(无论它们的可见性如何)。
  • @AngelicCore 我已经修改了我的答案以演示如何持久化数据。
猜你喜欢
  • 2017-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 2011-06-28
  • 1970-01-01
  • 2017-02-04
  • 2010-12-14
相关资源
最近更新 更多