上一篇文章介绍了简单的登录功能实现,也随便把SQL的帮助类也讲解了。其中SqlHelper这个类的构造函数我们在初始化连接字符串有两种方式,代码中有所体现了,一种就是直接赋值为需要的连接字符串,这种方式别人看不到你具体数据库的连接信息,但是不方便修改,每次修改都需要修改代码并且重新编译;第二种方式就是在配置文件中配置,这样我们的系统在运行到别的电脑上,只需要修改配置文件中的连接字符串信息就可以了,很方便。我们简单看一下配置文件的类容,讲解一下配置文件各个配置选项的意义。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <!--<add key="ConnectionString" value="Data Source=scdzyj;Persist Security Info=True;User ID=dzyj;Password=dzyj;Unicode=True" />--> <add key="ConnectionString" value="Data Source=BRUCEWOO;Persist Security Info=True;User ID=sde;Password=sde;Unicode=True;" /> <!--<add key="SERVER" value="10.51.6.233"/>--> <add key="SERVER" value="127.0.0.1"/> <add key="INSTANCE" value="port:5151"/> <add key="USER" value="sde"/> <add key="PASSWORD" value="sde"/> <add key="DATABASE" value="sde"/> <add key="VERSION" value="SDE.DEFAULT"/> </appSettings> </configuration>
上面的配置文件<!-- -->之间的是注释掉得内容,配置的key可以通过如下代码访问value的值:
ConfigurationSettings.AppSettings["ConnectionString"];//这一句代码就取得关键字ConnectionString所对应的value值
本系统的配置文件除了用于连接Oracle10g以外,下面还有一些是用于连接空间数据库的配置,具体的含义我会在涉及到空间数据库操作的时候会详细介绍,和怎样连接空间数据库一起介绍,因为和连接一般的关系型数据库还是很有区别的!
成功登陆以后我们就进入了整个系统的主界面,主界面采用了office2007的界面风格,并且实现了多种界面皮肤,可以任意切换,还有一个重要功能就是实现了多标签界面,这些功能都是利用第三方界面库实现了,这里不具体讲解这个界面库的使用了。不过既然是这么好的库不会使用实在是比较可惜,所以上传一个视频到CSDN下载区供需要使用的朋友下载使用,具体下载地址:http://download.csdn.net/detail/wanweiaiaqiang/3812891。如果不能访问请在下载区搜索资源名称“office风格界面库的视频教程”。光有视频教程肯定还是不行的,必须要有这个类似Office2007库文件才行,这个库文件提供的方式相对简单,既不需要你安装也不需要注册之类的,因为它是以DLL文件的形式提供,只需要你把这个DLL文件导入到你项目中的引用目录下就可以,同样这个文件我也上传到CSDN的下载区供需要使用的人下载(千万不要嫌需要的资源分多哦,毕竟我觉得物有所值呀,如果我没有这些之前,谁给我,我花20个积分也毫不犹豫,这里还是要求大家在下载的时候多评论,多努力帮助别人来整积分,我非常反感那种只知道索取而不奉献的人),下载地址是:http://download.csdn.net/detail/wanweiaiaqiang/3812964,如果不能找到可以向上面一样在下载区搜索“Office2007界面风格的DLL库文件”。我相信大部分人都应该知道怎么加载DLL文件到自己的项目中,为了少部分不会的博友们,我下面详细讲解一下这个过程。首先找到解决方案的那个小窗口,找到引用的那个目录,如下图所示:
然后单击鼠标右键选择第一项“添加引用(R)...”,这是会弹出一个添加引用的窗口,又然后切换到浏览界面,找到这个DLL文件(CSDN下载,我上传的),如下图所示:
随后点击上图的的确定按钮即可,就完成了一个DLL文件形式的函数库了。
下面就开始真正介绍主界面实现的功能,其实登录功能也是在这个主界面功能里面调用的,只是调用得比较早吧了,就是在这个主界面对于类的构造函数中调用,主界面构造函数实现如下:
public FrmMain() { Thread t = new Thread(Login); t.Start(); //m_AoInitialize = new AoInitializeClass(); //esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable; //licenseStatus = m_AoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo); InitializeComponent(); isInitFinish = true; while (username == null || username == "") { ; } }
如上代码首先启动一个登录线程,为什么需要使用单独的线程来登录,因为后面初始化ArcGIS需要几十秒的时间,为了不让用户等待太久,所以在用户输入登录用户名和密码的同时已经开始在初始化ArcGIS的相关组件了,这也是提高用户体验的一个很小的一个方面,但是不要因为小而不去做,只有把这些做到最细腻处,才能让我们的系统使用用户满意。注释的代码是用于初始化ArcGIS的License的,因为ArcGIS是收费软件,而且收费不低(根据功能不同收费也不同,企业版最贵,功能当然也是最强的),所以用ArcGIS开发都得购买他的License。我当时兼职的时候公司提供这些Licnese的,当然网上也有破解版的,我试过一些,有些确实可以使用的,在这里就不推荐了(我们还是尊重别人的知识版本,因为我们本来也是做软件开发的嘛);不过还有另一种方式可以使用,ArcGIS公司专门为了学习人员提供了一种途径,就是可以在官方去申请使用一个时间段,并且时间段到了以后还可以继续申请(这个我没有去试过,当时是听我们一个同事告诉我的),有兴趣的博友们可以去试试,如果成功了的话,可以写一篇博客介绍一些具体的申请过程,并将博客地址留言到此博客下面。因为自己的时间也是很有限的,白天需要上班,下班了还要学习和研究各种新技术,比如云计算、云存储、分布式计算、分布式文件系统,当然还有我最喜爱的linux源代码,最近研究的是linux3.1.RC4版本的内核,并且在现在的公司内部之间做了这方面的分享。我喜欢技术讨论和分享,如果谁要和我讨论技术的话,三天三夜我也不会觉得时间多。不过每个人的时间有限,学习的东西还是有限,所以只有通过多交流和分享来快速学习更多的知识,你看我嘛基本上所有的博客都是凌晨1点以后完成的。扯远了,回归代码,这里注释掉得原因是我在界面设计的时候拖了一个具有同样功能的控件(两种方式效果一样,只是拖动方便简单,而且界面设计的时候需要用到ArcGIS提供的控件就必须先拖动,不然会禁止使用并报错)。接着使用了一个bool变量来检查用户是否登录了,因为用户可能一直处于为登录状态,如果不判断就会直接进入主界面了(因为初始化随时都可能完成),这里使用用户名的值为不为空来判断,因为在登录函数中(也就是线程的入口函数)如果登录成功了回初始化用户名(也方便后面需要使用用户名的地方),代码如下:
//登陆线程,为了让License的初始化同步进行,缩短用户等待时间 private void Login() { FrmUserLogin ful = new FrmUserLogin(); ful.ShowDialog(); username = ful.getUsername(); }
下面看看多皮肤界面是通过怎样的代码实现的,详细实现过程情况上面提到的视频,代码如下:
多标签功能实
private void CommandTheme_Executed(object sender, EventArgs e) { ICommandSource source = sender as ICommandSource; if (source.CommandParameter is string) { eOffice2007ColorScheme colorScheme = (eOffice2007ColorScheme)Enum.Parse(typeof(eOffice2007ColorScheme), source.CommandParameter.ToString()); ribbonControl1.Office2007ColorTable = colorScheme; } else if (source.CommandParameter is Color) { RibbonPredefinedColorSchemes.ChangeOffice2007ColorTable(this, m_BaseColorScheme, (Color)source.CommandParameter); } this.Invalidate(); }
现如下,这个和视频里介绍的有一些出入,主要是后面发现会存在一些bug(多标签切换最大化照成的bug),按下面代码可以解决遇到的问题:
/// <summary> /// 检查是否已经打开某个子窗体,如果打开了就返回true,否则返回false。防止打开多个相同的窗体 /// </summary> /// <param name="tabName">窗体名称</param> /// <returns></returns> public bool IsOpenTab(string tabName) { bool isOpened = false; foreach (Form child in this.MdiChildren) { if (tabName == child.Text) { child.WindowState = FormWindowState.Maximized; } else { child.WindowState = FormWindowState.Normal; } } foreach (TabItem tab in tabStrip1.Tabs) { if (tab.Text.Trim() == tabName) { isOpened = true; tabStrip1.SelectedTab = tab; break; } } return isOpened; }
上面代码的第一个foreach循环首先根据子窗口的名称遍历所有子窗口(嵌套在主窗口里面的),如果以前以前存在的让他们的窗口状态(大小的状态)变成正常状态,让新建的窗口的最大化显示(不这样做会出现问题,可能照成程序自己退出或报错后退出),愿意是因为最大化子窗口竞争,同时只能允许一个最大化的子窗口。第二个foreach循环是让新建的这个子窗口的状态时处于打开状态,并且让停留条选择刚才新建的窗口显示(一个条形控件,所有子窗口以标签的形式停留在上面,点击这些标签可以切换子窗口显示)。
下面的代码就是根据每一个按钮所对应的功能来建立子窗口(可能是子窗口也可能是弹出一个模态的窗口,停留的都是非模态对话框,模态与非模态的区别可以查询google)。
//通用数据库管理 private void DataEdit_Click(object sender, EventArgs e) { string tabName = "数据管理"; if (!IsOpenTab(tabName)) { FrmDataManager dm = new FrmDataManager(); dm.MdiParent = this; dm.WindowState = FormWindowState.Maximized; dm.Show(); } } //图层分类定义 private void LayerManager_Click(object sender, EventArgs e) { string tabName = "图层分层标准定义"; if (!IsOpenTab(tabName)) { FrmLayerStandDefine dm = new FrmLayerStandDefine(); dm.MdiParent = this; dm.WindowState = FormWindowState.Maximized; dm.Show(); } } //空间数据导入 private void SpatialDataImport_Click(object sender, EventArgs e) { FrmSelectFileFormat fsff = new FrmSelectFileFormat(); fsff.ShowDialog(); } private void FrmMain_Load(object sender, EventArgs e) { SqlHelper sh = new SqlHelper(); string sql = "select department from jcsjk_users where username='" + username + "'"; OracleDataReader ord = sh.ReturnDataReader(sql); if (ord.Read()) { department = ord[0].ToString(); } } //日志管理 private void lookLogBtn_Click(object sender, EventArgs e) { string tabName = "日志管理"; if (!IsOpenTab(tabName)) { LogManager lm = new LogManager(); lm.MdiParent = this; lm.WindowState = FormWindowState.Maximized; lm.Show(); } } //元数据库管理 private void MetaDatabaseManager_Click(object sender, EventArgs e) { if (!metaIsLgoin) { FrmUserLogin ful = new FrmUserLogin(); ful.userType = 2; ful.ShowDialog(); } if (!metaIsLgoin) { return; } string tabName = "元数据库管理"; if (!IsOpenTab(tabName)) { FrmMetaDataBaseManage fmdbm = new FrmMetaDataBaseManage(); fmdbm.MdiParent = this; fmdbm.WindowState = FormWindowState.Maximized; fmdbm.Show(); } } //空间数据导出 private void SpatialDataExport_Click(object sender, EventArgs e) { FrmDataExport fde = new FrmDataExport(); fde.ShowDialog(); } //空间数据编辑 private void DataUpdate_Click(object sender, EventArgs e) { /* string tabName = "数据更新"; if (!IsOpenTab(tabName)) { FrmDataUpdate fsl = new FrmDataUpdate(); fsl.Text = "数据更新"; fsl.MdiParent = this; fsl.WindowState = FormWindowState.Maximized; SqlHelper sh = new SqlHelper(); string sql = string.Empty; sql = "select table_name from layer where type='PY' or type='PL' or type='PT'"; OracleDataReader odr = sh.ReturnDataReader(sql); while (odr.Read()) { fsl.AddLayerToMapCtl(odr[0].ToString(), true); } fsl.Show(); } FrmDataUpdate fsl = new FrmDataUpdate(); fsl.Text = "数据更新"; SqlHelper sh = new SqlHelper(); string sql = string.Empty; sql = "select table_name from layer where type='PY' or type='PL' or type='PT'"; OracleDataReader odr = sh.ReturnDataReader(sql); while (odr.Read()) { fsl.AddLayerToMapCtl(odr[0].ToString(), true); } fsl.ShowDialog(); */ string tabName = "空间数据编辑"; if (!IsOpenTab(tabName)) { FrmSpatialDataEdit fsde = new FrmSpatialDataEdit(); fsde.MdiParent = this; fsde.WindowState = FormWindowState.Maximized; fsde.Show(); } } //数据字典编辑 private void DataDictionaryEdit_Click(object sender, EventArgs e) { string tabName = "数据字典编辑"; if (!IsOpenTab(tabName)) { FrmDataDictionaryEdit dde = new FrmDataDictionaryEdit(); dde.MdiParent = this; dde.WindowState = FormWindowState.Maximized; dde.Show(); } } //数据字典查询 private void DataDictionaryQuery_Click(object sender, EventArgs e) { string tabName = "数据字典查询"; if (!IsOpenTab(tabName)) { FrmDataDictionaryQuery fddq = new FrmDataDictionaryQuery(); fddq.MdiParent = this; fddq.WindowState = FormWindowState.Maximized; fddq.Show(); } } //图库管理 private void MapLibManagement_Click(object sender, EventArgs e) { string tabName = "图库管理"; if (!IsOpenTab(tabName)) { FrmMapLibManagement fdx = new FrmMapLibManagement(); fdx.MdiParent = this; fdx.WindowState = FormWindowState.Maximized; fdx.Show(); } } //退出系统 private void ExitSystem_Click(object sender, EventArgs e) { Application.Exit(); } //元数据编辑 private void metaDataEdit_Click(object sender, EventArgs e) { if (!metaIsLgoin) { FrmUserLogin ful = new FrmUserLogin(); ful.userType = 2; ful.ShowDialog(); } if (!metaIsLgoin) { return; } else { string tabName = "元数据编辑"; if (!IsOpenTab(tabName)) { FrmMetaDataEdit fmde = new FrmMetaDataEdit(); fmde.MdiParent = this; fmde.WindowState = FormWindowState.Maximized; fmde.Show(); } } } //元数据的目录管理 private void MetaDataDirManager_Click(object sender, EventArgs e) { if (!metaIsLgoin) { FrmUserLogin ful = new FrmUserLogin(); ful.userType = 2; ful.ShowDialog(); } if (!metaIsLgoin) { return; } else { string tabName = "元数据目录管理"; if (!IsOpenTab(tabName)) { FrmDirManager fdm = new FrmDirManager(); fdm.MdiParent = this; fdm.WindowState = FormWindowState.Maximized; fdm.Show(); } } } //元数据查询子系统 private void MetaDataQuery_Click(object sender, EventArgs e) { if (!metaIsLgoin) { FrmUserLogin ful = new FrmUserLogin(); ful.userType = 2; ful.ShowDialog(); } if (!metaIsLgoin) { return; } else { string tabName = "元数据查询系统"; if (!IsOpenTab(tabName)) { FrmMetaDataQuery fmdq = new FrmMetaDataQuery(); fmdq.MdiParent = this; fmdq.WindowState = FormWindowState.Maximized; fmdq.Show(); } } } //元数据导入导出 private void MetaDataImport_Click(object sender, EventArgs e) { if (!metaIsLgoin) { FrmUserLogin ful = new FrmUserLogin(); ful.userType = 2; ful.ShowDialog(); } if (!metaIsLgoin) { return; } else { string tabName = "元数据导入导出"; if (!IsOpenTab(tabName)) { FrmMetaDataImport fmde = new FrmMetaDataImport(); fmde.MdiParent = this; fmde.WindowState = FormWindowState.Maximized; fmde.Show(); } } } //数据统计 private void DataStatistics_Click(object sender, EventArgs e) { string tabName = "数据统计"; if (!IsOpenTab(tabName)) { F_map fm = new F_map(); fm.MdiParent = this; fm.WindowState = FormWindowState.Maximized; fm.Show(); } } //标准导入 private void StandImport_Click(object sender, EventArgs e) { FrmLayerStandImport flsi = new FrmLayerStandImport(); flsi.ShowDialog(); } //数据集管理 private void DataSetManage_Click(object sender, EventArgs e) { string tabName = "数据集管理"; if (!IsOpenTab(tabName)) { FrmDataSetManage fdsm = new FrmDataSetManage(); fdsm.MdiParent = this; fdsm.WindowState = FormWindowState.Maximized; fdsm.Show(); } } //属性数据查询 private void DataAttributeQuery_Click(object sender, EventArgs e) { string tabName = "空间数据属性查询"; if (!IsOpenTab(tabName)) { FrmAttributeQuery faq = new FrmAttributeQuery(); faq.MdiParent = this; faq.WindowState = FormWindowState.Maximized; faq.Show(); } } //空间查询 private void SpatialQuery_Click(object sender, EventArgs e) { string tabName = "空间查询"; if (!IsOpenTab(tabName)) { FrmSpatialQuery fsq = new FrmSpatialQuery(); fsq.MdiParent = this; fsq.WindowState = FormWindowState.Maximized; fsq.Show(); } } //数据库备份 private void DatabaseBackup_Click(object sender, EventArgs e) { FrmDatabaseBackup fdb = new FrmDatabaseBackup(); fdb.ShowDialog(); } //数据库恢复 private void RestoreDatabase_Click(object sender, EventArgs e) { FrmRestoreDatabase frd = new FrmRestoreDatabase(); frd.ShowDialog(); } //监控日志查看 private void InspectLogShow_Click(object sender, EventArgs e) { FrmShowInspectLog fsil = new FrmShowInspectLog(); fsil.ShowDialog(); } //运维系统与制度 private void OperationMaintain_Click(object sender, EventArgs e) { string tabName = "运维系统与制度"; if (!IsOpenTab(tabName)) { FrmOperationMaintain fom = new FrmOperationMaintain(); fom.MdiParent = this; fom.WindowState = FormWindowState.Maximized; fom.Show(); } } //数据库监控与优化 private void Inspect_Click(object sender, EventArgs e) { string tabName = "数据库监控与优化"; if (!IsOpenTab(tabName)) { FrmDatabaseInspect fdi = new FrmDatabaseInspect(); fdi.MdiParent = this; fdi.WindowState = FormWindowState.Maximized; fdi.Show(); } }
上面都具体某一个函数是代表哪一个子模块或子系统的功能入口,以后的子功能和子系统的功能就在自己的界面和类中实现了。
主界面上的所有功能都已介绍完了,现在也是凌晨2:14,虽然明天周六不上班,但是还是有恨重要的事情需要去做,而且要出比较远的门(相对哈),因为一个要好的初中女同学要步入婚姻的殿堂了!
各位博友晚安加早安!