閱讀120 返回首頁    go 阿裏雲 go 技術社區[雲棲]


C# 係統應用之ListView控件 (二).加載選中節點文件夾下文件信息

在項目中的前麵一篇文章"C# 係統應用之TreeView控件 (一).顯示樹狀磁盤文件目錄及加載圖標"中我講述了如何使用TreeView控件樹狀實現顯示"我的電腦"所有磁盤路徑下的文件夾,並加載圖標如下圖所示.

此篇文章我需要講述的是當鼠標點擊左邊的TreeView控件中的文件夾時,如何實現在右邊的ListView控件中顯示相應的文件,並顯示文件的名稱、大小、類型屬性.主要運用的知識是如何實現ListView顯示信息,Subitems()函數增加子項,如何設置列表頭等信息.運行結果如下圖所示:

一.Load函數中加載ListView列標題頭

在前篇文章基礎上,把控件filesList(ListView控件)拉長,並設置Form1的屬性FormBorderStyle(窗體邊框和標題欄外觀)為FixedSingle,此時該窗體不能拖動拉長.通過Form1_Load()函數初始加載ListView的標題頭(名稱、大小、類型).代碼如下:

/// <summary>
/// 窗體加載Load事件 初始化
/// </summary>
private void Form1_Load(object sender, EventArgs e)
{
    ....
    //調用SetListView()函數初始化設置ListView
    SetListView();
}
/// <summary>
/// 自定義函數設置ListView控件初始屬性
/// </summary>
private void SetListView()
{
    //行和列是否顯示網格線
    this.filesList.GridLines = false;
    //顯示方式(注意View是Details詳細顯示)
    this.filesList.View = View.Details;
    //是否可編輯
    this.filesList.LabelEdit = true;
    //沒有足夠的空間顯示時,是否添加滾動條
    this.filesList.Scrollable = true;
    //對表頭進行設置
    this.filesList.HeaderStyle = ColumnHeaderStyle.Clickable;
    //是否可以選擇行
    this.filesList.FullRowSelect = true;

    //設置listView列標題頭 寬度為9/13 2/13 2/13 
    //其中設置標題頭自動適應寬度,-1根據內容設置寬度,-2根據標題設置寬度
    this.filesList.Columns.Add("名稱", 9 * filesList.Width / 13);   
    this.filesList.Columns.Add("大小", 2 * filesList.Width / 13);
    this.filesList.Columns.Add("類型", 2 * filesList.Width / 13);
}

二.AfterSelect事件實現ListView加載數據

現在需要在"解決方案"中點擊directoryTree(TreeView控件,左邊的樹狀圖控件)添加AfterSelect事件,當選中某個節點後,通過該事件顯示該文件夾下的所有文件信息.代碼如下:

#region ListView顯示選中文件夾中文件內容
/// <summary>
/// 獲取節點的路徑:遞歸調用產生節點對應文件夾的路徑
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private string GetPathFromNode(TreeNode node)
{
    //注意:樹形控件中我隻賦值Tag\Name,使用Text時賦值即可使用
    if (node.Parent == null)
    {
        return node.Name;
    }
    //Path.Combine組合產生路徑 如 Path.Combine("A","B")則生成"A\\B"
    return Path.Combine(GetPathFromNode(node.Parent), node.Name);
}

/// <summary>
/// 更改選定內容後發生 後去當前節點名字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void directoryTree_AfterSelect(object sender, TreeViewEventArgs e)
{
    try
    {
        //定義變量
        long length;                        //文件大小
        string path;                        //文件路徑
        TreeNode clickedNode = e.Node;      //獲取當前選中結點

        //移除ListView所有項 
        this.filesList.Items.Clear();       

        //獲取路徑賦值path              
        if (clickedNode.Tag.ToString() == "我的文檔")
        {
            //獲取計算機我的文檔文件夾
            path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        }
        else
        {
            //通過自定義函數GetPathFromNode獲取結點路徑
            path = GetPathFromNode(clickedNode);
        }

        //由於"我的電腦"為空結點,無需處理,否則會出現路徑獲取錯誤或沒有找到"我的電腦"路徑
        if (clickedNode.Tag.ToString() != "我的電腦")
        {
            //數據更新 UI暫時掛起直到EndUpdate繪製控件,可以有效避免閃爍並大大提高加載速度
            this.filesList.BeginUpdate();
            //實例目錄與子目錄
            DirectoryInfo dir = new DirectoryInfo(path);
            //獲取當前目錄文件列表
            FileInfo[] fileInfo = dir.GetFiles();
            //循環輸出獲取文件信息
            for (int i = 0; i < fileInfo.Length; i++)
            {
                ListViewItem listItem = new ListViewItem();
                //listItem.SubItems[0].Text = fileInfo[i].Name;             //文件名(方法二)
                listItem.Text = "[" + (i + 1) + "] " + fileInfo[i].Name;    //顯示文件名
                listItem.ForeColor = Color.Blue;                            //設置行顏色

                //length/1024轉換為KB字節數整數值 Ceiling返回最小整數值 Divide除法
                length = fileInfo[i].Length;                                //獲取當前文件大小
                listItem.SubItems.Add(Math.Ceiling(decimal.Divide(length, 1024)) + " KB");

                //獲取文件最後訪問時間
                //listItem.SubItems.Add(fileInfo[i].LastWriteTime.ToString());

                //獲取文件擴展名時可用Substring除去點 否則顯示".txt文件"
                listItem.SubItems.Add(fileInfo[i].Extension + "文件");
                //加載數據至filesList
                this.filesList.Items.Add(listItem);
            }
            //結束數據處理,UI界麵一次性繪製 否則可能出現閃動情況
            this.filesList.EndUpdate();  
        }
    }
    catch (Exception msg)  //異常處理
    {
        MessageBox.Show(msg.Message);
    } 
}
#endregion

三.遇到的問題

這篇文章看似簡單,其實過程遇到很多問題還是值得學習的.
1.遇到的第一個問題就是為什麼使用ListView控件總是隻顯示第一列數據呢?為什麼設置了列標題Columns沒有顯示出來呢?
因為我在程序中初始化後又添加一段代碼filesList.View = View.List;設置了View顯示的視圖為List.而View屬性包括五種顯示方式:Details(詳細信息)、List(列表)、LargeIcon(大圖標)、SmallIcon(小圖標)、Tile.默認時LargeIcon此時顯示為亂序,如果想顯示詳細信息一行一行的需要設置為Details.
這裏推薦大家閱讀夜之子的"
C# ListView用法詳解",真心神作!此處引用他文章中的4張圖區別View不同屬性顯示情況.
 

 

2.遇到的第二個問題主要是如何添加數據?如何添加列標題頭?
可以采用listItem.SubItems[0].Text添加,但是listItem.SubItems[1]時會報錯"InvalidArgument="1"的值對於"Index"無效.參數:index".估計原因是tem沒有填入123,所以我采用的方法是listItem.SubItems.Add添加.
3.使用"this.filesList.BeginUpdate()"和"this.filesList.EndUpdate()"數據更新時UI暫時掛起直到EndUpdate繪製控件,可以有效避免閃爍並大大提高加載速度.否則由於加載數據較大時會出現閃爍或空白遮擋等問題.

四.總結

最後希望該文章對大家有所幫助,感謝上麵提到的文章及作者.同時如果文章中有錯誤或不足之處請原諒,有問題或建議者亦可提出.希望尊重作者勞動果實.接下來想實現的是使用API函數添加文件圖標和實現右鍵打開文件和刪除文件的操作.僅以此篇文章紀念自己在CSDN發表50篇博客.
文件免費下載地址:https://download.csdn.net/detail/eastmount/7041767
MFC實現該功能類似文章:
https://blog.csdn.net/eastmount/article/details/19120567
(By:Eastmount 2014-3-14 下午6點 原創CSDNhttps://blog.csdn.net/eastmount/)

最後更新:2017-04-03 12:55:38

  上一篇:go 從研究生到程序員
  下一篇:go 關於Ubuntu 下新開發板adb 無法識別的問題(成功案例:解決了三星,索愛,OPPO X903案例)