NFace TreeViewer 和ListViewer(JFace Viewer在.Net中的簡單實現)
NFace的簡單實現
如果您熟悉JFace,那麼你最大的感觸是什麼?優良的設計框架?精簡易用的API?簡單方便的資料繫結?
以前做基於Eclipse RCP開發的時候,我被JFace的易用和思想吸引,感覺很優雅。JFace中的UI元件十分豐富,功能很多,今天想談談如何在.NET中實現其中的一兩個元件,也算是我技術BLOG開篇之作。對於.NET中TreeView的DataBinding,我很不喜歡,於是想到模仿JFace TreeViewer的介面寫一個.NET版本的NFace TreeViewer,另外將JFace TableViewer實現為NFace ListViewer。但這裡只說說TreeViewer的實現,ListViewer的思想是相同的。
一、首先看一下這兩個元件的類圖,懶得用建模畫UML了,下圖用VS2005自帶的ClassDiagram工具生成:
1.首先是CTreeViewer的類圖
1.1 CTreeNode繼承於TreeNode類
成員
|
說明
|
Data
|
用於存放業務資料(通常是實體類的例項),這樣,可以方便的在使用者點選樹上節點時,取得相應業務資料。
|
HasGotChildren
|
是否已經取得過子節點。
|
IsBlankNode
|
是否時空節點,空節點是看不到的節點,僅僅用於生成節點上的展開加號,這樣,當某個節點未展開時,其下有一個空節點,那麼就會形成加號。
|
NeedRefresh
|
節點是否需要重新整理。
|
CTreeNode(bool isBlankNode)
|
用是否空節點構造一個節點
|
CTreeNode(object obj)
|
用業務資料構造一個節點
|
CTreeNode(string text, object obj)
|
用節點顯示文字和業務資料構造一個節點
|
1.2 ITreeViewLabelProvider,CTreeViewer的顯示提供器
成員
|
說明
|
GetImageIndex(object obj)
|
獲取樹節點文字前的影象索引號
|
GetLabel(object obj)
|
獲取樹節點顯示的字串
|
GetSelectedImageIndex(object obj)
|
獲取樹節點被選中時文字前的影象索引號
|
1.3 ITreeViewContentProvider,CTreeViewer的內容提供器
成員
|
說明
|
GetElements()
|
獲根節點物件(可以有多個根節點)
|
GetElements(object obj)
|
獲取obj節點下的子節點
|
HasChildren(object obj)
|
判斷obj節點下是否有子節點
|
1.4 CTreeViewer類,繼承於TreeView
成員
|
說明
|
ContentProvider
|
CTreeViewer的內容提供器
|
LabelProvider
|
CTreeViewer的顯示提供器
|
GetChildrenWhenExpand
|
是否在展開樹節點是獲取其子節點,該屬性影響效能,設定為True時,節點展開時只獲取當前層的資料;設定為False時,每次展開一個節點不光獲取當前層的資料,也同時獲取當前層所有節點的子節點的資料(也就是每次展開一個節點獲取兩層節點資料)
|
ExpandToLevel(int)
|
展開樹到指定層
|
ExpandToLevelByThread(int)
|
展開樹到指定層(執行緒中完成)
|
RefreshOnlyOneNode(CTreeNode)
|
重新整理某個節點
|
OnAfterExpand(TreeViewEventArgs)
|
過載TreeView的展開後方法,完成獲取子節點,構造樹的工作
|
ShowTree()
|
根據給定的內容提供器和顯示提供器,構造顯示樹內容
|
2.然後是NFace ListViewer的類圖:
對於CListViewer的類圖不再作詳細解釋,類似CTreeViewer。
二、思想
實現IContentProvider和ILabelProvider後,CTreeViewer根據實現該介面的類例項來自動構造一顆樹,ContentProvider提供樹節點資料(後臺業務資料)以及資料之間的關係(父子節點關係),LabelProvider定義如何顯示樹節點(節點的圖示、文字內容)。
三、用法
這裡舉一個簡單的例子,將地區資訊顯示成一顆樹。該例中資料從XML讀取:
簡單說明一下:ID是某個地區的ID號,Name是地區名字,ParentID是上級地區的ID號,IsLeave表示是否是葉子地區(其下沒有子地區)。
3.1 新建一個WinForm程式,引入IZero.NFace.dll,在視窗上拖放一個CTreeViewer元件,取名為ctv。
3.2 實現一個ContentProvider
3.3 實現一個LabelProvider
3.4 在FormLoad事件裡,載入XML檔案到一個DataSet,以便待會兒傳入ContentProvider,並且對CTreeViewer的內容提供器和顯示提供器設定提供器。
3.5 在視窗上放一個顯示按鈕,在其單擊事件中,呼叫CTreeViewer的ShowTree()方法即可。
四、效果圖
今天先寫到這裡,關於CListViewer和CTreeViewer的使用,將會在後續篇幅中用到(可能是一個簡單的資料庫瀏覽器)。由於第一次寫技術BLOG,經驗不足,敬請諒解。
NFace原始碼和示例程式 下載地址: 目前似乎還不能上傳除圖片外的資源,不清楚是否支援。如果您想要原始碼和示例程式,請留下email,我會通過郵件傳送。
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<District>
<ID>0</ID>
<Name>中國</Name>
<ParentID>-1</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>1</ID>
<Name>美國</Name>
<ParentID>-1</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>2</ID>
<Name>日本</Name>
<ParentID>-1</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>3</ID>
<Name>韓國</Name>
<ParentID>-1</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>4</ID>
<Name>北京</Name>
<ParentID>0</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>5</ID>
<Name>上海</Name>
<ParentID>0</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>6</ID>
<Name>杭州</Name>
<ParentID>0</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>7</ID>
<Name>浦東新區</Name>
<ParentID>5</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>8</ID>
<Name>徐彙區</Name>
<ParentID>5</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>9</ID>
<Name>楊浦區</Name>
<ParentID>5</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>10</ID>
<Name>合慶鎮</Name>
<ParentID>7</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>11</ID>
<Name>張江鎮</Name>
<ParentID>7</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>12</ID>
<Name>川沙鎮</Name>
<ParentID>7</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>13</ID>
<Name>加州</Name>
<ParentID>1</ParentID>
<IsLeave>true</IsLeave>
</District>
</NewDataSet>
<NewDataSet>
<District>
<ID>0</ID>
<Name>中國</Name>
<ParentID>-1</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>1</ID>
<Name>美國</Name>
<ParentID>-1</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>2</ID>
<Name>日本</Name>
<ParentID>-1</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>3</ID>
<Name>韓國</Name>
<ParentID>-1</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>4</ID>
<Name>北京</Name>
<ParentID>0</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>5</ID>
<Name>上海</Name>
<ParentID>0</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>6</ID>
<Name>杭州</Name>
<ParentID>0</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>7</ID>
<Name>浦東新區</Name>
<ParentID>5</ParentID>
<IsLeave>false</IsLeave>
</District>
<District>
<ID>8</ID>
<Name>徐彙區</Name>
<ParentID>5</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>9</ID>
<Name>楊浦區</Name>
<ParentID>5</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>10</ID>
<Name>合慶鎮</Name>
<ParentID>7</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>11</ID>
<Name>張江鎮</Name>
<ParentID>7</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>12</ID>
<Name>川沙鎮</Name>
<ParentID>7</ParentID>
<IsLeave>true</IsLeave>
</District>
<District>
<ID>13</ID>
<Name>加州</Name>
<ParentID>1</ParentID>
<IsLeave>true</IsLeave>
</District>
</NewDataSet>
簡單說明一下:ID是某個地區的ID號,Name是地區名字,ParentID是上級地區的ID號,IsLeave表示是否是葉子地區(其下沒有子地區)。
3.1 新建一個WinForm程式,引入IZero.NFace.dll,在視窗上拖放一個CTreeViewer元件,取名為ctv。
3.2 實現一個ContentProvider
class ContentProvider : IZero.NFace.CTreeView.ITreeViewContentProvider
{
private DataSet ds;
public ContentProvider(DataSet ds)
{
this.ds =( ds == null ? new DataSet() : ds); //這裡資料集從建構函式傳入
}
ITreeViewContentProvider 成員
}
{
private DataSet ds;
public ContentProvider(DataSet ds)
{
this.ds =( ds == null ? new DataSet() : ds); //這裡資料集從建構函式傳入
}
ITreeViewContentProvider 成員
}
3.3 實現一個LabelProvider
class LabelProvider : IZero.NFace.CTreeView.ITreeViewLabelProvider
{
ITreeViewLabelProvider 成員
}
{
ITreeViewLabelProvider 成員
}
3.4 在FormLoad事件裡,載入XML檔案到一個DataSet,以便待會兒傳入ContentProvider,並且對CTreeViewer的內容提供器和顯示提供器設定提供器。
private void FrmTest_Load(object sender, EventArgs e)
{
DataSet ds = new DataSet();
try
{
ds.ReadXml("TestData.xml");
this.ctv.ContentProvider = new ContentProvider(ds);
this.ctv.LabelProvider = new LabelProvider();
this.ctv.GetChildrenWhenExpand = true; //Default is true
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
{
DataSet ds = new DataSet();
try
{
ds.ReadXml("TestData.xml");
this.ctv.ContentProvider = new ContentProvider(ds);
this.ctv.LabelProvider = new LabelProvider();
this.ctv.GetChildrenWhenExpand = true; //Default is true
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
3.5 在視窗上放一個顯示按鈕,在其單擊事件中,呼叫CTreeViewer的ShowTree()方法即可。
四、效果圖
今天先寫到這裡,關於CListViewer和CTreeViewer的使用,將會在後續篇幅中用到(可能是一個簡單的資料庫瀏覽器)。由於第一次寫技術BLOG,經驗不足,敬請諒解。
NFace原始碼和示例程式 下載地址: 目前似乎還不能上傳除圖片外的資源,不清楚是否支援。如果您想要原始碼和示例程式,請留下email,我會通過郵件傳送。
相關文章
- Swt/Jface tableviewer 加入filter ,改變行的顏色ViewFilter
- netty 實現簡單的rpc呼叫NettyRPC
- ACCESS 在資料表中實現簡單計算
- 在 Golang 中實現一個簡單的Http中介軟體GolangHTTP
- asp.net中sitemap的簡單實用ASP.NET
- MessagePack 序列化框架在netty中的簡單實現。框架Netty
- 在Unity中實現一個簡單的訊息管理器Unity
- Java使用Netty實現簡單的RPCJavaNettyRPC
- Redux 原理和簡單實現Redux
- throttle和debounce簡單實現
- 使用Netty和動態代理實現一個簡單的RPCNettyRPC
- 使用Beetle.NetPackage簡單實現android和wp聊天PackageAndroid
- 在ASP.NET中如何用C#.NET實現基於表單的驗證ASP.NETC#
- [原創視訊]PHP在netbeans中的簡單使用PHPBean
- comet在asp.net中的實現ASP.NET
- Redis在.net中的使用(3)簡單的主從複製Redis
- 簡單的11步在Laravel中實現測試驅動開發Laravel
- 簡單的 11 步在 Laravel 中實現測試驅動開發Laravel
- 在 SpringBoot 專案中簡單實現 JWT 驗證Spring BootJWT
- MVVM架構在Flutter中的簡單實踐MVVM架構Flutter
- Android中SharePreferences的簡單實現Android
- js中trim函式的簡單實現JS函式
- 實現一個簡單的在瀏覽器執行Dotnet編輯器瀏覽器
- 如何簡單高效的在程式碼中實現兩級快取的管理快取
- 簡單的Java實現Netty進行通訊JavaNetty
- 簡單實現.NET Hook與事件模擬Hook事件
- MVP在Android專案中的簡單體現MVPAndroid
- 在CGI中實現session的想法和實現 (轉)Session
- 聊一聊非對稱加密在介面引數中的簡單實現加密
- 在 DotNetty 中實現同步請求Netty
- 在.NET Core 中實現健康檢查
- netty系列之:在netty中實現執行緒和CPU繫結Netty執行緒
- 自己用 Netty 實現一個簡單的 RPCNettyRPC
- Node中EventEmitter理解與簡單實現MIT
- 實現簡單的BitMap
- ArrayList的簡單實現
- AOP的簡單實現
- 簡單的 HashMap 實現HashMap