C# 代码应该在用户控件内还是在使用它的窗体内

C# 代码应该在用户控件内还是在使用它的窗体内,c#,winforms,C#,Winforms,我有一个小的设计问题,由于某种原因,我找不到相关的谷歌搜索结果 我有一个在我的应用程序中使用的用户控件。 主窗体打开第二个窗体作为对话框。T 他的第二个表单是使用包含列表框的用户控件 当然,我希望在处理表单时保留列表框项,因此我在主表单中保留一个私有列表 List<string> _listofFirstCoordinates = new List<string>(); 另外,让用户控件成为持有它的表单的公共变量,这样就可以直接更改它,这是可行的还是糟糕的设计 编辑:

我有一个小的设计问题,由于某种原因,我找不到相关的谷歌搜索结果

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

当然,我希望在处理表单时保留列表框项,因此我在主表单中保留一个私有列表

List<string> _listofFirstCoordinates = new List<string>();
另外,让用户控件成为持有它的表单的公共变量,这样就可以直接更改它,这是可行的还是糟糕的设计

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

var _listofFirstCoordinates = new List<string>();
var_listofFirstCoordinates=new List();
往返。

正确的解决方案是将视图级关注点(在本例中,与
表单
用户控件
和UI控件相关的任何内容)从控制器和模型级关注点(在本例中,是应用程序的数据)中抽象出来

在不完全重新构建系统的情况下,您仍然可以在示例中应用这种关注点分离

您可以从概念上论证
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;
    }
}
class主窗体:窗体{
私有void ShowChildFormModal(){
ChildViewModel vm=新的ChildViewModel();
vm.Coordinates列表=。。。
vm.OtherData=。。。
ChildForm child=新的ChildForm();
LoadFromViewModel(vm);
child.ShowDialog();
SaveToViewModel(vm);
SaveToDatabase(vm);
}
}
类ChildViewModel{//这是一个POCO
公共列表协调列表;
公共数据;
}
类子窗体:窗体{
public void LoadFromViewModel(ChildViewModel虚拟机){
//通过直接将列表用作数据源来节省时间和麻烦,或者您也可以手动填充组合框
this.childUserControl.LoadFromViewModel(vm);
this.someOtherControl.Value=vm.OtherData;
}
public void SaveToViewModel(ChildViewModel虚拟机){
//完成这篇文章是读者的一个练习
//但基本上是将表单控件中的值复制到“vm”实例中
}
}
类ChildUserControl:UserControl{
public void LoadFromViewModel(ChildViewModel虚拟机){
this.comboBox.DataSource=vm.coordinates列表;
}
}

我认为这可能更适合代码审查。我应该补充一点,因为数据现在保存在表单之间来回的变量中,因为用户必须在提交并最终保存到数据库之前完成所有子表单。因此它是一个var_listofFirstCoordinates=new List();来来回回。这会改变您的回答吗?@AngelicCore ViewModel模式仍然适用,事实上它会使您的工作更轻松,因为单个ViewModel实例可以表示整个表单集合的状态(无论其可见性如何)。@AngelicCore我已修改了我的回答,以演示如何持久化数据。
var _listofFirstCoordinates = new List<string>();
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;
    }
}