1. 程式人生 > >c# xptable NET中最強,最全功能的表格控制元件

c# xptable NET中最強,最全功能的表格控制元件

[翻譯]

Mathew Hall.著XPTable - .NET ListView meets Java's JTable


[簡介]

由於專案需要,我需要定製一個ListView,它必須能夠在列中插入影象、下拉框、可上下調整的數字、進度條等等。由於已經有了一個Java下的背景,我將簡單地基於那個JTable封裝。

XPTable

[功能]

全定製視覺化介面
支援XP風格
輕易新增再定製的控制元件
可隱藏列
行、列、單元可以被Disable
每個單元、列可以有Tooltip
等等……


[XPTable]

XPTable包含下面的元件:
1. Table,
2. ColumnModel 和它的 Columns,
3. TableModel

和它的 Row 和 Cell,
4. Renderer
5. Editor

[控制元件使用]

首先載入控制元件到Toolbox上(新增一個Item,引用XPTable.dll

然後,拖動Table, ColumnModel 和 TableModel到Form上,設定Table的ColumnModel 和 TableModel屬性,新增Column到ColumnModel,新增Row 和 Cell到TableModel.

image

或者,直接使用程式碼設定:

Table table = new Table();
ColumnModel columnModel = new ColumnModel();
TableModel tableModel = new
TableModel();

// set the Table's ColumModel and TableModel
table.ColumnModel = columnModel;
table.TableModel = tableModel;

// add some Columns to the ColumnModel
columnModel.Columns.Add(new TextColumn("Text"));
columnModel.Columns.Add(new CheckBoxColumn("CheckBox"));
columnModel.Columns.Add(new ButtonColumn("Button"
));

// add some Rows and Cells to the TableModel
tableModel.Rows.Add(new Row());
tableModel.Rows[0].Cells.Add(new Cell("Text 1"));
tableModel.Rows[0].Cells.Add(new Cell("CheckBox 1", true));
tableModel.Rows[0].Cells.Add(new Cell("Button 1"));
tableModel.Rows.Add(new Row());
tableModel.Rows[1].Cells.Add(new Cell("Text 2"));
tableModel.Rows[1].Cells.Add(new Cell("CheckBox 2", false));
tableModel.Rows[1].Cells.Add(new Cell("Button 2"));

[color=green]Table[/color]



Table是一個簡單的物件,事實上,它並不知道如何顯示資料。而是,分別使用ColumnModel 和TableModel 控制列和單元等等。 Table的主要角色是管理繪製操作,傳遞事件給Renderer 和 Editor,以控制其行為。

ColumnModel

ColumnModel包含一個列的集合,這些列會在Table上顯示。它會跟蹤建立到指定列的CellRenderer CellEditor


TableModel

它包含即將顯示的Row集合。


Renderers

就象上面說的那樣,Table 並不知道如何繪製單元或列頭。想法,它使用稱為Renderers 的物件繪製這些。

Table 使用兩個不同型別的Render,一個是Renderers: CellRenderer 繪製Cell,還一個HeaderRenderer繪製Column Header。

CellRenderers

下面是所有XPTable提供的CellRenderer:
* ICellRenderer - Exposes common methods provided by Cell renderers.
* CellRenderer - Base class for all Cell renderers.
* TextCellRenderer - A CellRenderer that draws Cell contents as strings.
* ButtonCellRenderer - A CellRenderer that draws Cell contents as Buttons.
* CheckBoxCellRenderer - A CellRenderer that draws Cell contents as CheckBoxes.
* ImageCellRenderer - A CellRenderer that draws Cell contents as Images.
* NumberCellRenderer - A CellRenderer that draws Cell contents as numbers.
* ProgressBarCellRenderer - A CellRenderer that draws Cell contents as a ProgressBar.
* DropDownCellRenderer - Base class for CellRenderers that draw Cell contents like ComboBoxes.
* ComboBoxCellRenderer - A CellRenderer that draws Cell contents as a ComboBox.
* ColorCellRenderer - A CellRenderer that draws Cell contents as Colors.
* DateTimeCellRenderer - A CellRenderer that draws Cell contents as a DateTime.

每個CellRenderer的預設輸出如下:

image


定製CellRenderer

有兩種方法定製CellRenderer,一是繼承CellRenderer ,重寫其OnPaint 和 OnPaintBackground方法;另一種方法是實現ICellRenderer (需要做的比較多)。

下面是Table的內建TextCellRenderer的程式碼:

public class TextCellRenderer : CellRenderer
{
protected override void OnPaint(PaintCellEventArgs e)
{
base.OnPaint(e);

// don't bother going any further if the Cell is null
if (e.Cell == null)
{
return;
}

// make sure we have some text to draw
if (e.Cell.Text != null && e.Cell.Text.Length != 0)
{
// check whether the cell is enabled
if (e.Enabled)
{
e.Graphics.DrawString(e.Cell.Text, base.Font,
base.ForeBrush, base.ClientRectangle,
base.StringFormat);
}
else
{
e.Graphics.DrawString(e.Cell.Text, base.Font,
base.GrayTextBrush, base.ClientRectangle,
base.StringFormat);
}
}

// draw a focus rect around the cell if it is
// enabled and has focus
if (e.Focused && e.Enabled)
{
ControlPaint.DrawFocusRectangle(e.Graphics,
base.ClientRectangle);
}
}
}


HeaderRenderers

和CellRenderer不一樣,HeaderRenderer 繪製所有的列Header。

XPTable提供的HeaderRenderer有:

* IHeaderRenderer - Exposes common methods provided by Column header renderers.
* HeaderRenderer - Base class for Renderers that draw Column headers.
* XPHeaderRenderer - A HeaderRenderer that draws Windows XP themed Column headers.
* GradientHeaderRenderer - A HeaderRenderer that draws gradient Column headers.
* FlatHeaderRenderer - A HeaderRenderer that draws flat Column headers.

下圖顯示了內建的HeaderRenderer的動作:

image


可以通過下面的語句進行具體的指定:

Code: // get the table to use a FlatHeaderRenderer
// to draw the column headers
table.HeaderRenderer = new FlatHeaderRenderer();



定製HeaderRenderer

下面是內建的XPHeaderRenderer的程式碼:

public class XPHeaderRenderer : HeaderRenderer
{
protected override void OnPaintBackground(PaintHeaderEventArgs e)
{
base.OnPaintBackground(e);

if (e.Column == null)
{
ThemeManager.DrawColumnHeader(e.Graphics, e.HeaderRect,
ColumnHeaderStates.Normal);
}
else
{
ThemeManager.DrawColumnHeader(e.Graphics, e.HeaderRect,
(ColumnHeaderStates) e.Column.ColumnState);
}
}


protected override void OnPaint(PaintHeaderEventArgs e)
{
base.OnPaint(e);

// don't bother if we don't have a column
if (e.Column == null)
{
return;
}

Rectangle textRect = base.ClientRectangle;
Rectangle imageRect = Rectangle.Empty;

// check whether we can draw an image on the column header
if (e.Column.Image != null)
{
imageRect = base.CalcImageRect();
textRect.Width -= imageRect.Width;
textRect.X += imageRect.Width;

if (e.Column.ImageOnRight)
{
imageRect.X = base.ClientRectangle.Right - imageRect.Width;
textRect.X = base.ClientRectangle.X;
}

// column headers that aren't themed and are pressed need
// their contents shifted down and to the right by 1 pixel
if (!ThemeManager.VisualStylesEnabled &&
e.Column.ColumnState == ColumnState.Pressed)
{
imageRect.X += 1;
imageRect.Y += 1;
}

base.DrawColumnHeaderImage(e.Graphics, e.Column.Image,
imageRect, e.Column.Enabled);
}

// column headers that aren't themed and are pressed need
// their contents shifted down and to the right by 1 pixel
if (!ThemeManager.VisualStylesEnabled &&
e.Column.ColumnState == ColumnState.Pressed)
{
textRect.X += 1;
textRect.Y += 1;
}

// check whether we need to draw a sort arrow
if (e.Column.SortOrder != SortOrder.None)
{
// work out where to draw it
Rectangle arrowRect = base.CalcSortArrowRect();

// adjust the textRect to take the arrow into account
arrowRect.X = textRect.Right - arrowRect.Width;
textRect.Width -= arrowRect.Width;

base.DrawSortArrow(e.Graphics, arrowRect, e.Column.SortOrder,
e.Column.Enabled);
}

// check whether we have any text to draw
if (e.Column.Text == null)
{
return;
}

if (e.Column.Text.Length > 0 && textRect.Width > 0)
{
if (e.Column.Enabled)
{
e.Graphics.DrawString(e.Column.Text,
base.Font, base.ForeBrush,
textRect, base.StringFormat);
}
else
{
using (SolidBrush brush =
new SolidBrush(SystemPens.GrayText.Color))
{
e.Graphics.DrawString(e.Column.Text,
base.Font, brush,
textRect, base.StringFormat);
}
}
}
}
}



Editors

5個內建的編輯器如下:

* ICellEditor - Exposes common methods provided by Cell editors.
* CellEditor - Base class for Cell editors.
* TextCellEditor - A class for editing Cells that contain strings.
* NumberCellEditor - A class for editing Cells that contain numbers.
* DropDownCellEditor - Base class for editing Cells that contain drop down buttons.
* ComboBoxCellEditor - A class for editing Cells that look like a ComboBox.
* ColorCellEditor - A class for editing Cells that contain Colors.
* DateTimeCellEditor - A class for editing Cells that contain DateTimes.
* IEditorUsesRendererButtons - Specifies that a CellEditor uses the buttons provided by its counter-part CellRenderer during editing.

見下圖:

image


按下面的程式碼,編輯一個單元:

Code: // start editing the cell at (0, 0)
table.EditCell(0, 0);

// stop editing the cell and commit any changes
table.StopEditing();

// or cancel editing and ignore any changes
table.CancelEditing();



定製CellEditor

下面是內建的TextCellEditor的程式碼:

public class TextCellEditor : CellEditor
{
public TextCellEditor() : base()
{
TextBox textbox = new TextBox();
textbox.AutoSize = false;
textbox.BorderStyle = BorderStyle.None;

base.Control = textbox;
}


// Sets the location and size of the CellEditor
protected override void SetEditLocation(Rectangle cellRect)
{
this.TextBox.Location = cellRect.Location;
this.TextBox.Size = new Size(cellRect.Width-1,
cellRect.Height-1);
}


// Sets the initial value of the
// editor based on the contents of
// the Cell being edited
protected override void SetEditValue()
{
this.TextBox.Text = base.EditingCell.Text;
}


// Sets the contents of the Cell
// being edited based on the value
// in the editor
protected override void SetCellValue()
{
base.EditingCell.Text = this.TextBox.Text;
}


// Starts editing the Cell
public override void StartEditing()
{
this.TextBox.KeyPress +=
new KeyPressEventHandler(OnKeyPress);
this.TextBox.LostFocus +=
new EventHandler(OnLostFocus);

base.StartEditing();

this.TextBox.Focus();
}


// Stops editing the Cell and commits any changes
public override void StopEditing()
{
this.TextBox.KeyPress -=
new KeyPressEventHandler(OnKeyPress);
this.TextBox.LostFocus -=
new EventHandler(OnLostFocus);

base.StopEditing();
}


// Stops editing the Cell and ignores any changes
public override void CancelEditing()
{
this.TextBox.KeyPress -=
new KeyPressEventHandler(OnKeyPress);
this.TextBox.LostFocus -=
new EventHandler(OnLostFocus);

base.CancelEditing();
}


// Gets the TextBox used to edit the Cells contents
public TextBox TextBox
{
get
{
return base.Control as TextBox;
}
}


// Handler for the editors TextBox.KeyPress event
protected virtual void OnKeyPress(object sender,
KeyPressEventArgs e)
{
// check whether we nned to stop or cancel editing
if (e.KeyChar == AsciiChars.CarriageReturn /*Enter*/)
{
if (base.EditingTable != null)
{
base.EditingTable.StopEditing();
}
}
else if (e.KeyChar == AsciiChars.Escape)
{
if (this.EditingTable != null)
{
base.EditingTable.CancelEditing();
}
}
}


// Handler for the editors TextBox.LostFocus event
protected virtual void OnLostFocus(object sender,
EventArgs e)
{
// if the textbox loses focus
// we should stop editing
if (base.EditingTable != null)
{
base.EditingTable.StopEditing();
}
}
}



風格

下面的程式碼顯示如何共享CellStyle 和 Rowstyle:

// create a new CellStyle object
CellStyle cellStyle = new CellStyle();
cellStyle.BackColor = Color.Blue;
cellStyle.ForeColor = Color.Red;
cellStyle.Font = new Font("Tahoma", 8.25f, FontStyle.Bold);

// create a new RowStyle object
RowStyle rowStyle = new RowStyle();
rowStyle.BackColor = Color.Yello;
rowStyle.ForeColor = Color.Green;
rowStyle.Font = new Font("Arial", 8.25f, FontStyle.Italics);

for (int i=0; i<3; i++)
{
tableModel.Rows[i].RowStyle = rowStyle;

// only set the cellstyle for cells in the 3rd column
tableModel[i, 2].CellStyle = cellStyle;
}



排序

排序是基於列的,當點選在Header的時候,執行。

有六種內建的比較器:

* ComparerBase - Base class for Cell comparers.
* TextComparer - for comparing Cells based on the Text property.
* CheckBoxComparer - for comparing Cells based on the Checked property.
* NumberComparer - for comparing Cells that contain numbers in the Data property.
* ImageComparer - for comparing Cells based on the Image property.
* ColorComparer - for comparing Cells that contain Colors in the Data property.
* DateTimeComparer - for comparing Cells that contain DateTimes in the Data property.

四種排序機制:

* InsertionSorter
* MergeSorter
* ShellSorter
* HeapSorter

你可以通過呼叫table的Sort 方法對一列進行排序:

// sort the currently sorted column in the opposite direction
// to its currnent sort order, or if no columns are sorted, the
// column that has focus in ascending order
table.Sort();

// sort the currently sorted column in the opposite direction
// to its currnent sort order, or if no columns are sorted, the
// column that has focus in ascending order using an unstable
// sort method
table.Sort(false);

// sort the column at index 3 in the table's ColumnModel
// opposite to its current sort order, or in ascending order
// if the column is not sorted
table.Sort(3);

// sort the column at index 3 in the table's ColumnModel
// opposite to its current sort order, or in ascending order
//if the column is not sorted using a stable sort method
table.Sort(3, true);

// sort the column at index 3 in the table's ColumnModel
// in descending order
table.Sort(3, SortOrder.Descending);

// sort the column at index 3 in the table's ColumnModel
// in ascending order using an unstable sort method
table.Sort(3, SortOrder.Ascending, false);



還可以設定屬性,不允許排序:

Code: // disable sorting for a column
column.Sortable = false;



定製比較器

public class TextComparer : ComparerBase
{
// Compares two objects and returns a
// value indicating whether one is less
// than, equal to or greater than the other
public override int Compare(object a, object b)
{
Cell cell1 = (Cell) a;
Cell cell2 = (Cell) b;

// check for null cells
if (cell1 == null && cell2 == null)
{
return 0;
}
else if (cell1 == null)
{
return -1;
}
else if (cell2 == null)
{
return 1;
}

// check for null data
if (cell1.Text == null && cell2.Text == null)
{
return 0;
}
else if (cell1.Text == null)
{
return -1;
}

// now that we know both cells contain valid data,
// use the frameworks built in string comparer
return cell1.Text.CompareTo(cell2.Text);
}
}




被選單元Selections

被選中的單元通常會被高亮:

image


你可以設定這個風格:

Code: // use grid style selection
table.SelectionStyle = SelectionStyle.Grid;



即將增加的功能

* Word wrapping for cells and column headers
* Autosizing rows and columns
* Variable height rows
* LinkLabel cells
* RichTextFormat cells
* Dialog based CellEditors
* ListView style icon mode
* RightToLeft support
* Cut and paste support
* Drag and drop support
* Data binding
* Column re-ordering
* Printing support
* Export to HTML and XML
* Serialization
* Other stuff I've forgotten or haven't thought of yet

相關推薦

c# xptable NET,功能表格控制元件

[翻譯]Mathew Hall.著XPTable - .NET ListView meets Java's JTable[簡介]由於專案需要,我需要定製一個ListView,它必須能夠在列中插入影象、下拉框、可上下調整的數字、進度條等等。由於已經有了一個Java下的背景,我將簡單地基

ASP.NETTextbox後的必填驗證控制元件RequiredFieldValidator的使用方法。

製作效果如下: 實現方法: 1. 拖動RequiredFieldValidator控制元件到相應的textbox後位置,點選屬性面板,輸入ErroMessage相應資訊,更改ForeColor為紅色 設定ControlToValidate為相應的要驗證的TextBox控制

ASP.NET動態獲取資料使用Highcharts圖表控制元件

<%@ Page Title="" Language="C#" MasterPageFile="~/MyHome/MasterPage.master" AutoEventWireup="true" CodeFile="ryfb.aspx.cs" Inherits="MyHome_tixi_ryfb"%&

常用開發庫 - 日誌類庫詳解

Java日誌庫是最能體現Java庫在進化中的淵源關係的,在理解時重點理解日誌框架本身和日誌門面,以及比較好的實踐等。要關注其歷史淵源和設計(比如橋接),而具體在使用時查詢介面即可, 否則會陷入JUL(Java Util Log), JCL(Commons Logging), Log4j, SLF4J, Lo

C# Asp.netxml串與對象互相轉換

try res return class 類型 mls log throw XML public class XmlUtil { #region 反序列化 /// <summary> /// 將XML字符

C# 在.net序列化讀寫xml方法的總結

XML是一種很常見的資料儲存方式,我經常用它來儲存一些資料,或者是一些配置引數。 使用C#,我們可以藉助.net framework提供的很多API來讀取或者建立修改這些XML, 然而,不同人使用XML的方法很有可能並不相同。 今天我打算談談我使用XML的一些方法,供大家參考。 回到頂部 最簡單的

C#(Winform) 當前執行緒不在單執行緒單元,因此無法例項化 ActiveX 控制元件

解決方案: 1、在主執行緒中例項化此ActiveX控制元件 2、將建立此Active控制元件的執行緒設定為單執行緒。       Thread.ApartmentState 獲取或設定此執行緒的單元狀態。             newThread= new Thre

python的tab補功能新增

用Python時沒有tab補全還是挺痛苦的,記錄一下新增該功能的方法利人利己 1. 先準備一個tab.py的指令碼   shell> cat tab.py 1 2 3 4 5 6 7 8

如何實現asp.netFileUpload檔案型別過濾功能

<script type="text/javascript"> function openfile() { try { var fd = new ActiveXObje

asp.net DropDownList 加入可輸入功能解決方案

先把這段JS程式碼放到你頁面的HTML中去 function catch_keydown(sel) { switch(event.keyCode) { case 13: //Enter; sel.options[sel.length] = new Option("",

C#如何遍歷datagridview表格控制元件的每一個格子(每一個單元格)

如下程式碼,用兩個for迴圈即可,給每一個格子賦空值:  for (int i = 0; i < this.dgvHistoricDataMng.Rows.Count; i++)             {                 for (int j = 0

簡單也難——如何獲取到Android控制元件的高度

問題 如何獲取一個控制元件的長和高,相信很多朋友第一眼看見這個問題都會覺得很簡單,直接在onCreate裡面呼叫getWidth、getMeasuredWidth不就可以獲得了嗎,但是,事實上是並沒有簡單的,不信的話,你可以去試一下,在onCreate裡面,你

C#主窗體Panel載入其他多個窗體Panel控制元件

今天在技術群裡,筆者遇到一個這樣的問題,“有客戶想讓兩個Form窗體的內容放到一個Form窗體中,但是兩個窗體的內容超出主窗體的大小”,為了解決這個問題,筆者的想法是“採用panel+滑動條方式解決以上問題”,下面就跟筆者一起來看看。 首先,筆者寫了四個For

C#.NET常見問題(FAQ)-如何使用變數訪問控制元件屬性

不管哪種型別的控制元件,可以用下面這種強制轉換和Controls.Find的方法來讀寫控制元件的屬性 //我在介面上做了三個picturebox控制元件 PictureBox p; //注意索引必須從1開始,並且不能超過Form中實際存在的控制元件數量(把1改成0或者把4改成

C# winform一個類如何呼叫另一個窗體的控制元件或方法

轉載地址:http://blog.csdn.net/ichenqingyun/article/details/52622340 一種是建立窗體物件的方式,通過物件呼叫控制元件或方法 例如: Form1 form1 = new Form1(); form1.Button;

asp.net + ajax + sqlserver 自動補功能

程式碼下載頁面:http://download.csdn.net/detail/zhanghui_hn/6994105 說明:資料庫連線字串在web.config檔案中,為方便執行使用的是官方的Northwind資料庫。 參考(向其作者致敬): ²  http://ww

ASP.NET 伺服器控制元件插入客戶端指令碼(自定義控制元件)

用於:Microsoft® ASP.NET前提條件:本文假設讀者熟悉 ASP.NET。難度: 2摘要:儘管從技術角度講,ASP.NET 伺服器控制元件的所有功能都可以在伺服器端執行,但通常情況下通過新增客戶端指令碼可以大大增強伺服器控制元件的可用性。本文將探討伺服器控制元件傳

Android引入佈局和和自定義控制元件

首先是引入佈局: 1.我們自己新建一個layout,就是一個標題欄。 2.然後在我們的mainactivity_layout中使用一個語句就可以實現。 <?xml version="1.0" encoding="utf-8"?> <LinearLayout

C# Panel滾動條滾動後,動態建立的控制元件下移的問題

C#做了一個從伺服器獲取資料的功能,動態建立控制元件顯示在Panel中,控制元件多的時候比Panel還高,滑動滾動條檢視中間資料,此時獲取到資料,,動態新增時,發現控制元件全部下移了,上面空出好大一部分空白。 除錯發現,即使控制元件的Location設定為new Point(0, 0);上面也空

C語言Windows程式開發—Windows視窗樣式與常用控制元件樣式【第04天】

(一)Windows視窗(MDICLIENT)樣式介紹 1 /* Windows視窗樣式 */ 2 WS_BORDER //帶有邊框的視窗 3 WS_CAPTION //帶有標題欄的視窗 4 WS_CHILD