C# 使用WinForms MDI子窗口执行以下操作
因此,我正在使用WinForms在C#中构建一个MDI应用程序。我一辈子都搞不清楚在这种情况下如何遵循DRY。我正在使用主菜单条中的toolstripmenuitems打开新的MDI子菜单。我已将“NewChild”方法重新用作每个方法的事件处理程序。我尽量不必为每个子窗口重复我自己,因为它们都遵循相同的实例化模式 我已经研究了泛型和类型类的使用,但它并没有真正达到我的目的。理想情况下,我只想说C# 使用WinForms MDI子窗口执行以下操作,c#,winforms,dry,mdi,C#,Winforms,Dry,Mdi,因此,我正在使用WinForms在C#中构建一个MDI应用程序。我一辈子都搞不清楚在这种情况下如何遵循DRY。我正在使用主菜单条中的toolstripmenuitems打开新的MDI子菜单。我已将“NewChild”方法重新用作每个方法的事件处理程序。我尽量不必为每个子窗口重复我自己,因为它们都遵循相同的实例化模式 我已经研究了泛型和类型类的使用,但它并没有真正达到我的目的。理想情况下,我只想说 // etc... TypeOfForm = ConfigurationForm;
// etc...
TypeOfForm = ConfigurationForm;
}
new TypeOfForm();
但我认为不存在这样的语言结构
public partial class MainForm : Form
{
private AboutForm aboutForm;
private ConfigurationForm configForm;
private ResultsForm resultForm;
private LogForm logForm;
private void NewChild(object sender, EventArgs e)
{
Form newForm;
if (sender == testConfigurationToolStripMenuItem)
{
if (configForm == null)
{
configForm = new ConfigurationForm();
}
newForm = configForm;
}
else if (sender == resultsToolStripMenuItem)
{
if (resultForm == null)
{
resultForm = new ResultsForm();
}
newForm = resultForm;
}
else if (sender == logToolStripMenuItem)
{
if (logForm == null)
{
logForm = new LogForm();
}
newForm = logForm;
}
else
{
return;
}
newForm.MdiParent = this;
newForm.Disposed += new EventHandler(ChildDisposed);
newForm.Show();
}
}
在这种情况下,实现DRY的好方法是什么?我会不惜一切代价避免检查类型。它真的会把代码弄得乱七八糟 您确实希望对以下通用代码使用泛型:
// for multiple instance forms (and instantiating a "singleton" form)
private void AddNewChild<T>() where T: Form
{
T newForm = new T();
newForm.MdiParent = this;
newForm.Disposed += new EventHandler(ChildDisposed);
newForm.Show();
}
// for "singleton" forms
private void ActivateChild<T>() where T: Form
{
// off-the-cuff guess, this line may not work/compile
var child = this.MdiChildren.OfType<T>().FirstOrDefault();
if (child == null)
{
AddNewChild<T>();
}
else
{
child.Show();
}
}
// usage
logToolStripMenuItem.Click += (s,e) => ActivateChild<LogForm>();
testConfigurationToolStripMenuItem.Click += (s,e) => ActivateChild<ConfigurationForm>();
multipleInstanceFormMenuItem.Click += (s,e) => AddNewChild<FormX>();
...
//用于多实例表单(并实例化“单例”表单)
私有void AddNewChild(),其中T:Form
{
T newForm=newt();
newForm.MdiParent=此;
Disposed+=neweventhandler(ChildDisposed);
newForm.Show();
}
//“单身”表格
私有void ActivateChild(),其中T:Form
{
//即兴猜测,这一行可能不起作用/无法编译
var child=this.mdichilds.OfType().FirstOrDefault();
if(child==null)
{
AddNewChild();
}
其他的
{
child.Show();
}
}
//用法
logToolStripMenuItem.单击+=(s,e)=>ActivateChild();
testConfigurationToolStripMenuItem。单击+=(s,e)=>ActivateChild();
multipleInstanceFormMenuItem。单击+=(s,e)=>AddNewChild();
...
这里有一个建议:
使用toolstrip对象(或使用Tag属性)及其匹配的表单或表单类型创建字典
// you can't use the UI controls before Init, you could use their Tags
// so this should be considered pseudo code
private Dictionary<string, Type> ToolstripForms = new Dictionary<string, Type>
{
{ testConfigurationToolStripMenuItem, typeof(ConfigurationForm) },
{ resultsToolStripMenuItem, typeof(ResultsForm) },
};
您可能需要一种方法来确定表单是否已经打开,并关注它,而不是每次都打开一个新表单,但这取决于您。一种方法是使用一对对象作为该字典中的值—类型和现有实例,尽管其他方法可能看起来更好。尝试更改此行
newForm.MdiParent=this
tonewForm.MdiParent=this.MdiParent代码>我很困惑,我是从MDI父级创建这些子表单的(这个),为什么我要看这个。MDI父级?谢谢,这正是我要找的,我不明白C是如何实现泛型的。
private void NewChild(object sender, EventArgs e)
{
Form newForm = null;
// some casting and exception handling would go well here
if (sender != null && ToolstripForms.ContainsKey(sender)) // or sender.Tag?
{
newForm = Activator.CreateInstance(ToolstripForms[sender]) as Form;
}
...
}