本文系原创,转载请注明出处:
https://blog.csdn.net/chengbao315/article/details/82722254
在一个实际应用的项目中,常常会用到框架开发,因为使用框架易于移植,可以降低开发成本,同时可以保证系统的稳定性,而且对于立志成为架构师的朋友,学习框架开发也是必不可少的。接下来的几篇文章中,我会分享一些自己在项目中总结的框架开发经验,欢迎朋友们留言参与讨论,不足之处多多指教。
今天想介绍一个简单的“上-中-下”结构的框架,“上”一般是标题、导航之类的内容,“中”主要是软件的主体内容,“下”可以是页脚,也可以是一些用于切换界面按钮(有时这个部分也会放在主窗体左侧,根据需要设计)。
好了,还是老规矩,先上效果图:
简单做了一个示例界面,比较丑,以后我会出一个界面美化系列的文章,这里请无视他的丑(捂脸)。
看到这个界面,大家可能会觉得实现起来还是挺简单的,但是使用框架的话,还是让我研究了一段时间。总结起来,这里用到了反射和事件方面的知识。
首先,我们先按上面的设计做好布局,分别用三个panel作为“上”、“中”、“下”三个部分的容器,“下”这个部分根据自己需要放置几个按钮。接下来,根据自己的需要,可以添加几个Module界面,这里添加的是用户控件。
接下来,我们可以创建一个Module帮助类,我这里起名叫ModuleActivator.css,然后再添加一个枚举,把我们的Module添加进去(注意:这里的枚举一定要和Module的类名一致,因为我们要靠他转化成实体):
public enum ModuleType
{
Unknown,
UserControl1,
UserControl2,
UserControl3
}
回到我们的主窗体,我们在初始化时可以对按钮进行界面的绑定(这里的applekey就是我主窗体的三个按钮):
private void InitButton()
{
this.appleKey1.Tag = ModuleType.UserControl1;
this.appleKey2.Tag = ModuleType.UserControl2;
this.appleKey3.Tag = ModuleType.UserControl3;
}
接下来实现我们的Module帮助类,我们需要在类中添加两个事件,添加模块和移除模块事件,并且实现切换界面的方法,直接上代码,仔细看代码注释。
public class ModuleActivator
{
private ModuleType selectedModuleType;
// 主窗体实体
private object mainModule;
// 添加模块事件
public event EventHandler ModuleAdded;
// 移除模块事件
public event EventHandler ModuleRemoved;
// 当前选择的模块类型
public ModuleType SelectedModuleType { get { return selectedModuleType; } }
// 当前选择的模块实体
public object SelectedModule
{
get;
set;
}
// 构造方法时传入主窗体实体
public ModuleActivator(object mainModule)
{
this.mainModule = mainModule;
}
/// <summary>
/// 选择模块时进行切换界面
/// </summary>
/// <param name="moduleType"></param>
public void SelectModule(ModuleType moduleType)
{
// 如果选择的module类型不变,不切换
if (SelectedModuleType == moduleType) return;
var old = SelectedModuleType;
this.selectedModuleType = moduleType;
// 切换module
OnSelectedModuleChanged(old);
}
/// <summary>
/// 切换界面的方法
/// </summary>
/// <param name="oldType"></param>
protected void OnSelectedModuleChanged(ModuleType oldType)
{
if (oldType != ModuleType.Unknown)
{
// 获取旧模块实体
object oldModule = this.GetModule(oldType);
if (oldModule != null)
{
// 如果注册了移除模块事件
if (ModuleRemoved != null)
{
// 触发事件
ModuleRemoved(oldModule, EventArgs.Empty);
}
}
}
if(selectedModuleType != ModuleType.Unknown)
{
// 获取新模块实体
SelectedModule = GetModule(SelectedModuleType);
if (SelectedModule != null)
{
// 如果注册了添加模块事件
if (ModuleAdded != null)
{
// 触发事件
ModuleAdded(SelectedModule, EventArgs.Empty);
}
}
}
}
/// <summary>
/// 获取module实体
/// </summary>
/// <param name="moduleType"></param>
/// <returns></returns>
public object GetModule(ModuleType moduleType)
{
if (moduleType == ModuleType.Unknown) return null;
var mainModuleType = this.mainModule.GetType();
// 获取module实体类型
var moduleTpye = mainModuleType.Assembly.GetType(mainModuleType.Namespace + "." + moduleType.ToString());
// 使用反射生成module实体
return Activator.CreateInstance(moduleTpye);
}
}
再次回到主窗体,我们在初始化时同样要创建一个module帮助类,并且注册他的两个事件,在事件处理中进行Module切换以及module基本属性的设置,代码如下:
private void InitModule()
{
this.module = new ModuleActivator(this);
this.module.ModuleAdded += viewModel_ModuleAdded;
this.module.ModuleRemoved += viewModel_ModuleRemoved;
}
private void viewModel_ModuleAdded(object sender, EventArgs e)
{
var moduleControl = sender as Control;
moduleControl.Dock = DockStyle.Fill;
moduleControl.Size = panel2.ClientSize;
moduleControl.Parent = panel2;
}
private void viewModel_ModuleRemoved(object sender, EventArgs e)
{
panel2.Controls.Clear();
}
写到这里,我们的小框架基本上就大功告成了,只需要给按钮添加一个click事件,在事件处理中调用module的选择方法就可以了,看代码:
private void appleKey1_Click(object sender, EventArgs e)
{
module.SelectModule((ModuleType)(sender as AppleKey).Tag);
}
最后看看我们的最终效果吧:
好了,今天就到这里,欢迎大家提出疑问和意见,下篇文章我继续更新,感谢大家的支持~
最后,给大家推荐一下我创建的公众号,在里面会发一些技术文章以及博客的更新推送,欢迎大家关注,再次感谢大家的支持!
扫描二维码,关注我的微信公众号