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