基于ArcGIS10.0和Oracle10g的空間數據管理平臺三(C#開發)-多皮膚主界面功能
上一篇文章介紹了簡單的登錄功能實現,也隨便把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,雖然明天周六不上班,但是還是有恨重要的事情需要去做,而且要出比較遠的門(相對哈),因為一個要好的初中女同學要步入婚姻的殿堂了!
各位博友晚安加早安!
浙公網安備 33010602011771號