AddData(添加數據)對話框的實現與擴展(C#)

先看兩張圖,第一張是AE自帶的Add data對話框, 相信所有做AE開發的人都見過;另一張是本人仿製和擴展的添加數據對話框,大家肯定沒見過。



各位筒子,有沒有覺得十分震撼?這是我整整一天的勞動結晶,下面就讓我來隆重介紹一下。
我的風格是有所保留的奉獻源碼,無所顧忌的貢獻思路。
爲什麼做這個東西
一個原因是本人可能是極端分子,在做軟件時,要麼全部用中文,要麼全部用英文,最不喜歡半洋半中,因此一直有個宏偉的計劃,就是將AE裏面自帶的對話框和浮動窗體都重做一下,這個工作仍然在進行中;另一個原因是AE自帶的這個對話框只能加載其指定的數據類型,連Desktop中支持的CAD圖都不能加載,就別說自定義的數據類型了,以前的做法重新寫一個命令來加載這些數據,這讓我很反感,所以一直想自己設計一個添加數據的對話框。
這個東西是怎麼做的
網上有通過Windows API函數直接擴展Windows對話框如打開文件對話框的例子,但十分複雜,而且也不一定能做出我想要的效果。其實自己動手做一個普通對話框不難,但做一個打開文件的對話框難在何處呢?我們先看看AE自帶的Add data對話框的結構:頂部是一個下拉列表框,可以以樹狀的形式顯示驅動器和文件夾;左邊是幾個按鈕,起過濾文件類型的作用;正中是一個列表框,可以顯示驅動器、文件夾、文件的信息;底部有一個文本框用於顯示文件名,一個下拉列表框,用於選擇文件類型,還有兩個按鈕,一個是打開按鈕,一個是取消按鈕。好了,通過分析這個對話框的結構,我們就可以發現實現的難點在何處了。
難點一:如何實現一個樹狀的下拉列表框;
難點二:如何獲取計算機中的驅動器、文件夾和文件信息;
難點三:如何分門別類的加載各種數據。
實際上,後面兩個都是比較容易解決的,關鍵就是第一個了,於是我又想到第三方控件以及我的最愛開源網站www.codeproject.com了,往上一搜,果然有人寫過,讓我喜出望外的是,作者的目的也是爲了仿製一個Window打開文件對話框,這就好辦了。
這款第三方控件名爲ExplorerControls,提供了好幾個做界面的控件,大家可以去看看,網址是:http://www.codeproject.com/KB/cpp/ExpCombo.aspx
接下來開始動手,首先是設計界面,費了不少功夫,做一個漂亮的界面真不是件容易的事,甚至比寫程序還累。這個界面的主角當然是ExplorerControls中的Brower控件了,這個控件由一個下拉列表和一個列表框組成,基本實現了打開文件框中相應的部分,即在下拉列表中選擇驅動器和文件夾,在列表框中顯示文件夾和文件。browser需要設置許多屬性,大家可參照源碼來做。
下面就要寫代碼了。
一、點擊左邊按鈕過濾文件類型的功能的實現
很簡單,brower有一個Filter屬性,可以設置你想要的所有文件類型,注意這是一個string數組。下面是一個過濾raster的按鈕的單擊事件。

private void btnFilterRaster_Click(object sender, EventArgs e)
{
    this.browser.Filter = new string[] { "img","tif","tiff","jpg","jpeg","bmp","gif","png"};
    this.browser.RefreshBrowser();
    this.cmbDataType.Items.Clear();
    this.cmbDataType.Items.AddRange( new string[] {
    "所有支持的文件 (*.img,*.tif,*.tiff,*.jpg,*.jpeg,*.bmp,*.gif,*.png)",
    "Imagine image文件 (*.img)",
    "TIFF文件 (*.tif)",
    "TIFF文件 (*.tiff)",
    "JPEG文件 (*.jpg)",
    "JPEG文件 (*.jpeg)",
    "位圖文件 (*.bmp)",
    "PNG文件 (*.png)",
    "GIF文件 (*.gif)"
     });
     this.cmbDataType.SelectedIndex = 0;
     g_pDataType = 3;
}
其中,cmbDataType是文件類型的下拉列表框,g_pDataType是標誌,用於判斷打開的是什麼類型的數據。

二、在列表框中單擊文件返回文件路徑,單擊文件夾打開文件夾
brower公開了一個SelectedListIndexChanged事件,可以在個事件中添加相應代碼,如下所示:

        private void browser_SelectedListIndexChanged(object sender,EventArgs e)
        {
            string SelectFileName="";
            m_ShitemList = new List<CShItem>();
            ExplorerControls.ExpList.SelectedExpListItemCollection ExpListCol = this.browser.SelectedListItems;
            if (ExpListCol.Count == 0) return;
            else if (ExpListCol.Count == 1)
            {
                ExpListItem pExpListItem = ExpListCol[0];
                CShItem shItem;
                shItem = pExpListItem.CShItem;
                if (shItem.IsFolder)
                {
                    m_shItem_1 = shItem;
                    this.txtFileName.Text = "";
                    return;
                }
                else
                {
                    m_ShitemList.Add(shItem);
                    m_shItem_1 = null;
                }
              
                SelectFileName = pExpListItem.Text;
                this.txtFileName.Text = SelectFileName;
            }
            else
            {
                foreach (ExpListItem pExpListItem in ExpListCol)
                {
                    CShItem shItem;
                    shItem = pExpListItem.CShItem;
                    if (shItem.IsFolder)
                    {
                        m_shItem_1 = shItem;
                        this.txtFileName.Text = "";
                        return;
                    }
                    else
                    {
                        m_ShitemList.Add(shItem);
                        m_shItem_1 = null;
                    }
                    SelectFileName += pExpListItem.Text;
                    SelectFileName += "; ";
                }
                SelectFileName = SelectFileName.Remove(SelectFileName.Length - 1);
                this.txtFileName.Text = SelectFileName;
            }
        }
其中CShitem是一個十分重要的類,在這個類中提供了諸如文件路徑path的屬性,也提供了諸如判斷所選項是文件夾還是文件的方法isforder,這些東西十分有用。由於brower支持多選,所以定義了一個list數組m_ShitemList來存儲列表框中被選定的所有項。txtFileName是一個用於顯示文件名的文本框。


三、將文件的雙擊事件綁定到打開按鈕
看如下代碼:

private void browser_FileActivate(object sender, ExpList.ExpListItemEventArgs e)
        {
            this.btnOpen.PerformClick();
        }

四、在打開按鈕中實現打開各種數據的代碼
加載各種數據的代碼在論壇中很多,這裏不再重複。
這樣,工作就完成了,當然中間有很多細節我無法一一表述,大家不妨也動動手,DIY一個自己的添加數據對話框。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章