介紹 SourceGrid是一個完全用c#編寫的Windows窗體控件,我的目標是創建一個簡單但靈活的網格,用於所有需要以表格格式可視化或更改一系列數據的情況。 這種類型的控件有很多,但通常都很昂貴、難以定制或不兼容。網。 對於我來說,微軟的DataGrid過於以數據集為導向,因此在源數據不是數據集的情況下,其結果使用起來常常很復雜,而且通常不能進行足夠的定制。 我要感謝Chirs Beckett, Anthony Berglas, Wayne Tanner, Ernesto Perales, Vadim Katsman, Jeffery Bell, Gmonkey, cmwalolo, Kenedy, zeromus, Darko Damjanovic, John Pierre和其他很多人,他們在代碼,bug報告和新的想法和建議上幫助了我。 該控件是用Microsoft框架編譯的。dll 1.2.0.0,這是一個具有通用功能的小庫。我在ZIP文件中介紹了這個dll,但是可以從站點http://sourcegrid.codeplex.com/下載整個代碼和最后一個二進制文件。為了使用SourceGrid,必須有Visual Studio。NET 2003或兼容的開發環境。 該控件的最后一個版本可以從站點http://sourcegrid.codeplex.com/下載。 在本文中,我將提供關於控件SourceGrid的使用和功能的全景介紹,有關類、屬性或方法的詳細信息,您可以參考CHM格式的文檔或ZIP文件中的示例項目。 使用SourceGrid 在程序集SourceGrid2.dll中有兩個控件,它們可以插入到Visual Studio的工具箱中,並以任何形式使用: 網格虛擬單元格(ICellVirtual)。網格-真實細胞的網格(ICell)。 因此,有兩個基本區別要做:虛擬單元和真實單元。虛擬單元格是決定單元格外觀和行為但不包含值的單元格,真實單元格具有與虛擬單元格相同的屬性但也包含單元格的值,因此它們與網格的特定位置相關聯。 每個細胞由三個基本部分組成: DataModel: DataModel是管理單元格值的類。將單元格的值轉換為字符串的可視表示形式,創建單元格的編輯器並驗證插入的值。VisualModel: VisualModel是繪制單元格並包含可視化屬性的類。BehaviorModel: BehaviorModel是提供單元格行為的類。 這種細分為代碼提供了極大的靈活性和可重用性,節省了時間,並為每種類型的定制提供了堅實的基礎。 對於更常見的情況,已經有一些類進行了安排和配置,但是使用很少的代碼行就可以創建個性化的單元格(詳細信息請參閱下一段)。 網格 如果您想要最大的靈活性和簡單性,但是沒有太多單元格,那么Grid控件是最理想的。實際上,在這個控件中,每個單元格都由。net類表示,因此占用了特定數量的資源。此外,這是唯一支持RowSpan和ColumnSpan特性的網格。 將控件插入到窗體后,我們可以開始編寫代碼,在窗體的加載事件中使用網格,如下所示: 隱藏,復制Code
grid1.Redim(2, 2); grid1[0,0] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 0,0"); grid1[1,0] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 1,0"); grid1[0,1] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 0,1"); grid1[1,1] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 1,1");
前面的代碼創建了一個有2行2列的表(Redim方法),並使用一個單元格填充每個位置。我已經使用了SourceGrid2.Cells。真實的名稱空間,其中包含所有真實的單元。 每個單元格包含所有必要的顯示屬性,例如改變單元格的背景顏色,我們可以寫: 隱藏,復制Code
SourceGrid2.Cells.Real.Cell l_Cell = new SourceGrid2.Cells.Real.Cell( "Custom back color"); l_Cell.BackColor = Color.LightGreen; grid1[0,0] = l_Cell;
這些是單元格的主要視覺屬性(整個列表可以參考網格的文檔):背景色、前飾顏色、邊框、字體、TextAlignment, WordWrap… 現在我們嘗試創建一個帶有標題、自動排序、用鼠標調整列大小、字符串和日期時間編輯器以及復選框的整個網格。 隱藏,復制Code
grid1.BorderStyle = BorderStyle.FixedSingle; grid1.ColumnsCount = 3; grid1.FixedRows = 1; grid1.Rows.Insert(0); grid1[0,0] = new SourceGrid2.Cells.Real.ColumnHeader("String"); grid1[0,1] = new SourceGrid2.Cells.Real.ColumnHeader("DateTime"); grid1[0,2] = new SourceGrid2.Cells.Real.ColumnHeader("CheckBox"); for (int r = 1; r < 10; r++) { grid1.Rows.Insert(r); grid1[r,0] = new SourceGrid2.Cells.Real.Cell("Hello " + r.ToString(), typeof(string)); grid1[r,1] = new SourceGrid2.Cells.Real.Cell( DateTime.Today, typeof(DateTime)); grid1[r,2] = new SourceGrid2.Cells.Real.CheckBox(true); } grid1.AutoSizeAll();
在前面的代碼中,我設置了網格邊界、列數、固定行數,並創建了第一個標題行。對於標題,我使用了ColumnHeader單元格。有了一個簡單的循環,我就為每列創建了一個特定類型的其他單元格。Cell類為指定的類型自動創建適當的編輯器(在本例中是文本框和DateTimePicker)。對於最后一列,我使用了允許在單元格上直接顯示復選框的復選框單元格。 表單應該與下圖中的表單相同ample在項目SampleProject中也有ZIP文件。 GridVirtual 當需要對大量單元格進行可視化,並且您已經有了結構數據(如數據集、數組、文檔XML或其他數據結構)時,GridVirtual控件是理想的選擇。 這種類型的網格具有與網格控件相同的特性,除了自動排序(這是因為網格在不復制其內容的情況下無法自動排序任何外部數據結構),以及RowSpan和ColumnSpan的特性(允許跨相鄰單元跨越一個單元格)。 另一個缺點是創建虛擬網格有點困難。 虛擬網格的主要概念是單元格不包含值,而是在外部數據結構中讀取和寫入值。這個想法是通過一個抽象類CellVirtual實現的,需要在這個類中重新定義GetValue和SetValue方法。 因此,要使用GridVirtual,必須創建一個從CellVirtual派生的類,並使用所選的數據源對讀取進行個性化設置。 通常最好還創建一個派生自GridVirtual的控件,以獲得更大的靈活性和更可靠的代碼,重寫GetCell方法。 如果願意,可以直接使用GridVirtual控件和事件GettingCell。方法GetCell和事件GettingCell的目的是對於給定的位置(行和列)返回所選的單元格。這允許很大的靈活性,因為您可以為特定類型返回any ICellVirtual,例如,您可以在行為0時返回類型為header的單元格。 在下面的示例中,我創建了一個虛擬網格,用於讀取和寫入數組中的值。首先我在窗體中插入了GridVirtual控件,然后我寫了這個代碼來定義我們的虛擬類: 隱藏,復制Code
public class CellStringArray : SourceGrid2.Cells.Virtual.CellVirtual { private string[,] m_Array; public CellStringArray(string[,] p_Array):base(typeof(string)) { m_Array = p_Array; } public override object GetValue(SourceGrid2.Position p_Position) { return m_Array[p_Position.Row, p_Position.Column]; } public override void SetValue(SourceGrid2.Position p_Position, object p_Value) { m_Array[p_Position.Row, p_Position.Column] = (string)p_Value; OnValueChanged(new SourceGrid2.PositionEventArgs(p_Position, this)); } }
在前面的代碼中,我使用string類型的編輯器創建了一個虛擬單元格,該編輯器讀取和寫入構造函數中指定的數組中的值。 在調用SetValue方法之后,我們應該調用OnValueChanged方法來通知網格更新這個單元格。 在事件加載的形式,我已經插入這段代碼: 隱藏,復制Code
private void frmSample15_Load(object sender, System.EventArgs e) { gridVirtual1.GettingCell += new SourceGrid2.PositionEventHandler( gridVirtual1_GettingCell); gridVirtual1.Redim(1000,1000); string[,] l_Array = new string[gridVirtual1.RowsCount, gridVirtual1.ColumnsCount]; m_CellStringArray = new CellStringArray(l_Array); m_CellStringArray.BindToGrid(gridVirtual1); }
我為GettingCell事件添加了一個事件處理程序,創建了網格和1000行1000列的數組,然后創建了前一個單元格的新實例,並使用BindToGrid方法將單元格鏈接到網格。 我已經創建了一個單元格,它將用於矩陣的每個位置。在我們希望在虛擬網格中使用的單元格上調用BindToGrid方法時,始終是必需的。 為了完成這個任務,我們應該編寫GettingCell方法並聲明單元格的變量: 隱藏,復制Code
private CellStringArray m_CellStringArray; private void gridVirtual1_GettingCell(object sender, SourceGrid2.PositionEventArgs e) { e.Cell = m_CellStringArray; }
結果應該與下圖中的結果相同,這個示例也出現在ZIP文件中包含的項目SampleProject中。 VisualModel 名稱空間:SourceGrid2.VisualModels 每個單元格都有一個屬性VisualModel,它返回一個類型為IVisualModel的接口。單元格使用此界面繪制和自定義單元格的可視屬性。 VisualModel的目的是將繪圖代碼從其余代碼中分離出來,並允許在更多的單元格之間共享相同的可視化模型。實際上,同一個VisualModel實例可以在更多的單元上使用,同時優化系統資源的使用。 默認的VisualModel類是只讀的,但是每個VisualModel都提供了一個克隆方法,允許您創建相同模型的相同實例。 這些是命名空間SourceGrid2.VisualModels中的默認VisualModel類: SourceGrid2.VisualModels。常用-用於經典細胞。在這個模型中,您可以自定義顏色、字體、邊框和許多其他屬性。 SourceGrid2.VisualModels。-用於復選框樣式的單元格。復選框可以被選中、禁用,並且可以包含標題。 SourceGrid2.VisualModels。* -用於具有3D邊框的標題樣式單元格。您可以配置邊框,使其從邊框的顏色逐漸消失為單元格的顏色,以獲得更好的三維效果。 SourceGrid2.VisualModels。允許在單元格中繪制多個圖像。 *用星號標記的VisualModel需要一個特殊的界面才能正常工作,例如復選框模型需要一個支持ICellCheckBox界面的單元格。 每個類都包含一個或多個靜態屬性和一些容易使用的默認只讀實例: SourceGrid2.VisualModels.Common.Default SourceGrid2.VisualModels.Common.LinkStyle SourceGrid2.VisualModels.CheckBox.Default SourceGrid2.VisualModels.CheckBox.MiddleLeftAlign SourceGrid2.VisualModels.Header.Default 年代ourceGrid2.VisualModels.Header.ColumnHeader SourceGrid2.VisualModels.Header.RowHeader 這段代碼展示了如何將相同的VisualModel分配給更多先前創建的單元格,然后改變一些屬性: 隱藏,復制Code
SourceGrid2.VisualModels.Common l_SharedVisualModel = new SourceGrid2.VisualModels.Common(); grid1[0,0].VisualModel = l_SharedVisualModel; grid1[1,0].VisualModel = l_SharedVisualModel; grid1[2,0].VisualModel = l_SharedVisualModel; l_SharedVisualModel.BackColor = Color.LightGray;
在寫Cell時也要考慮。這個屬性自動調用VisualModel關聯的BackColor屬性。以便在編寫單元格時使用更常用的屬性。背景色= Color.Black;單元格會自動克隆當前的VisualModel,為克隆的實例更改背景色,並將克隆的實例再次分配給單元格。 DataModel 名稱空間:SourceGrid2.DataModels 要以字符串格式表示單元格的值並提供單元格數據編輯器,需要填充單元格的屬性DataModel。如果此屬性為null,則不可能更改單元格的值,並且字符串轉換將是一個簡單的ToString值。 通常,數據模型使用所要求的類型的類型轉換來管理必要的轉換,特別是字符串轉換(用於表示單元格值)。 這些是名稱空間sourcegrid . datamodels中的默認數據模型類: DataModelBase——提供轉換方法,只允許通過代碼更改單元格值,不提供圖形界面。該類是所有其他編輯器的基礎,也用於管理只讀單元格,但使用自定義格式或特殊編輯器(例如,復選框單元格使用只讀編輯器,因為直接單擊復選框會更改值)。 幫助將控件用作單元格的編輯器的抽象類。 一個文本框編輯器。這是所有支持字符串轉換的類型(字符串,int, double, enum,…)更常用的編輯器之一。 一個組合框編輯器。 一個DateTimePicker編輯器。 一個數字向上向下的編輯器。 一個文本框編輯器,帶有一個按鈕來打開詳細信息蒙版。 提供對所有具有UITypeEditor的類型的單元格的編輯。很多類型都支持這個接口:DateTime、字體、很多枚舉等等。 數據模型可以在更多的單元之間共享,例如,可以對列的每個單元使用相同的數據模型。 創建一個可編輯的單元格有兩種可能: 創建指定值類型的單元格。通過這種方式,單元格自動調用效用函數utility。CreateDataModel,它將基類型中的數據模型返回給指定的類型。 隱藏,復制Codegrid1[0,0] = new SourceGrid2.Cells.Real.Cell("Hello", typeof (string)); 分別創建數據模型,然后將其分配給單元格: 隱藏,CodeSourceGrid2.DataModels副本。IDataModel l_SharedDataModel = SourceGrid2.Utility.CreateDataModel (typeof (string)); grid1(0,0)。DataModel = l_SharedDataModel; grid1(1,0)。DataModel = l_SharedDataModel; 如果希望對多個單元格使用同一編輯器,建議使用此方法。 如果您需要更好地控制編輯器的類型,或者有特殊的需求,可以手動創建編輯器類。 例如,在本例中,我手動創建類EditorTextBox,然后調用屬性MaxLength和character腸管。 隱藏,復制Code
SourceGrid2.DataModels.EditorTextBox l_TextBox = new SourceGrid2.DataModels.EditorTextBox(typeof(string)); l_TextBox.MaxLength = 20; l_TextBox.AttachEditorControl(grid1); l_TextBox.GetEditorTextBox(grid1).CharacterCasing = CharacterCasing.Upper; grid1[2,0].DataModel = l_TextBox;
一些屬性定義為數據模型級別,而另一些屬性定義為編輯器控件級別,在本例中,屬性特征定義為文本框控件級別。因此,使用這些屬性需要使用AttachEditorControl方法強制編輯器鏈接到網格,然后調用方法GetEditorTextBox返回文本框的實例。 這個機制對於創建像ComboBox編輯器這樣的特殊編輯器也很有用。要插入一個組合框,你必須編寫以下代碼: 隱藏,復制Code
SourceGrid2.DataModels.EditorComboBox l_ComboBox = new SourceGrid2.DataModels.EditorComboBox( typeof(string), new string[]{"Hello", "Ciao"}, false); grid1[3,0].DataModel = l_ComboBox;
當然,也可以使用自定義控件或特殊行為創建自定義數據模型編輯器。 在下面的圖片中,可以觀察到大多數編輯器可用和一些選項,如圖像屬性: BehaviorModel 名稱空間:SourceGrid2.BehaviorModels 每個單元格都有一個行為模型的集合,你可以通過行為屬性讀取它。行為模型是描述細胞行為的類。模型可以在更多的單元之間共享,並且允許任何新特性的極大靈活性和簡單性。 這些是行為模型類型的默認類: SourceGrid2.BehaviorModels。Common -細胞的常見行為。 SourceGrid2.BehaviorModels。標題-標題的行為。 SourceGrid2.BehaviorModels。行標題的行為,具有調整大小的功能。 SourceGrid2.BehaviorModels。ColumnHeader* -列h的行為ader,具有排序和調整大小的功能。(需要 ICellSortableHeader) SourceGrid2.BehaviorModels。復選框* -復選框的行為。(需要 ICellCheckBox) SourceGrid2.BehaviorModels。游標* -允許將游標鏈接到特定的單元格。(需要 ICellCursor) SourceGrid2.BehaviorModels。按鈕-按鈕的行為。 SourceGrid2.BehaviorModels。Resize -允許用鼠標調整單元格的大小(這個模型被標題模型自動使用)。 SourceGrid2.BehaviorModels。允許顯示鏈接到單元格的工具提示文本。(需要 ICellToolTipText) SourceGrid2.BehaviorModels。不可選擇-阻止單元格接收焦點。 SourceGrid2.BehaviorModels。允許顯示一個鏈接到單元格的上下文菜單。(需要一個 ICellContextMenu) SourceGrid2.BehaviorModels。CustomEvents——公開一個不從行為模型派生而可以使用的事件列表。 SourceGrid2.BehaviorModels。BindProperty—允許將單元格的值鏈接到外部屬性。 SourceGrid2.BehaviorModels。允許創建一個自動調用一系列行為模型的行為模型(BehaviorModelGroup) 行為需要其他行為才能正常工作。 *用星號標記的BehaviorModel需要特殊的單元格來完成它們的任務,例如類復選框需要一個支持接口ICellCheckBox的單元格。 每個類都有一些靜態屬性,返回類的默認實例: SourceGrid2.BehaviorModels.Common.Default SourceGrid2.BehaviorModels.Button.Default SourceGrid2.BehaviorModels.CheckBox.Default SourceGrid2.BehaviorModels.ColumnHeader.SortableHeader SourceGrid2.BehaviorModels.ColumnHeader.NotSortableHeader SourceGrid2.BehaviorModels.Cursor.Default SourceGrid2.BehaviorModels.Header.Default SourceGrid2.BehaviorModels.Resize.ResizeHeight SourceGrid2.BehaviorModels.Resize.ResizeWidth SourceGrid2.BehaviorModels.Resize.ResizeBoth SourceGrid2.BehaviorModels.RowHeader.Default SourceGrid2.BehaviorModels.ToolTipText.Default SourceGrid2.BehaviorModels.Unselectable.Default 在下面的代碼示例中,我創建了一個行為模型,當用戶將鼠標移到單元格上時,它可以改變單元格的背景顏色。 隱藏,復制Code
public class CustomBehavior : SourceGrid2.BehaviorModels.BehaviorModelGroup { public override void OnMouseEnter(SourceGrid2.PositionEventArgs e) { base.OnMouseEnter (e); ((SourceGrid2.Cells.Real.Cell)e.Cell).BackColor = Color.LightGreen; } public override void OnMouseLeave(SourceGrid2.PositionEventArgs e) { base.OnMouseLeave (e); ((SourceGrid2.Cells.Real.Cell)e.Cell).BackColor = Color.White; } }
使用這個行為模型插入加載事件的表單,這段代碼: 隱藏,復制Code
grid1.Redim(2,2); CustomBehavior l_Behavior = new CustomBehavior(); for (int r = 0; r < grid1.RowsCount; r++) for (int c = 0; c < grid1.ColumnsCount; c++) { grid1[r,c] = new SourceGrid2.Cells.Real.Cell("Hello"); grid1[r,c].Behaviors.Add(l_Behavior); }
細胞 名稱空間:SourceGrid2.Cells 這些是默認的單元格可用: SourceGrid2.Cells。Virtual -這個名稱空間包含了GridVirtual控件可以使用的所有虛擬單元格,這些都是抽象單元格,您必須從這些單元格派生出您的自定義數據源。 CellVirtual -基單元格為彼此實現的,用於最常見的虛擬單元格類型。 標題-標題單元格。 ColumnHeader -列標題單元格。 行標題單元格。 按鈕-一個按鈕單元格。 復選框-一個復選框單元格。 組合框-組合框單元格。 鏈接-鏈接樣式的單元格。 SourceGrid2.Cells。Real——此名稱空間包含可用於網格控件的所有實際單元格。 單元格-基單元格為彼此實現,用於最常見的實單元格類型。 標題-標題單元格。 ColumnHeader -列標題單元格。 行標題單元格。 按鈕-一個按鈕單元格。 復選框-一個復選框單元格。 組合框-組合框單元格。 鏈接-鏈接樣式的單元格。 這些類的目標是簡化VisualModel、DataModel和BehaviorModel的使用。如果我們查看這些類的代碼,我們可以看到這些類根據單元格的角色使用前面的模型。然而,有些模型需要特殊的接口,在這種情況下,單元實現了所有需要的接口。 例如,這是單元格SourceGrid2.Cells.Real.CheckBox的代碼: 隱藏,收縮,復制Code
public class CheckBox : Cell, ICellCheckBox { public CheckBox(string p_Caption, bool p_InitialValue) { m_Caption = p_Caption; DataModel = new SourceGrid2.DataModels.DataModelBase(typeof(bool)); VisualModel = SourceGrid2.VisualModels.CheckBox.MiddleLeftAlign; Behaviors.Add(BehaviorModels.CheckBox.Default); Value = p_InitialValue; } public bool Checked { get{return GetCheckedValue(Range.Start);} set{SetCheckedValue(Range.Start, value);} } private string m_Caption; public string Caption { get{return m_Caption;} set{m_Caption = value;} } public virtual bool GetCheckedValue(Position p_Position) { return (bool)GetValue(p_Position); } public virtual void SetCheckedValue( Position p_Position, bool p_bChecked) { if (DataModel!=null && DataModel.EnableEdit) DataModel.SetCellValue(this, p_Position, p_bChecked); } public virtual CheckBoxStatus GetCheckBoxStatus(Position p_Position) { return new CheckBoxStatus(DataModel.EnableEdit, GetCheckedValue(p_Position), m_Caption); } }
正如您所看到的,復選框類只是簡單地使用模型sourcegrid . datamodelbase (typeof(bool)), sourcegrid . visualmodels .CheckBox。MiddleLeftAlign e BehaviorModels.CheckBox。Default使用方法GetCheckBoxStatus實現ICellCheckBox接口。 Checked、Caption、GetCheckedValue和SetCheckedValue方法都是簡化單元格值編輯的方法。 網格結構 行和列 網格的主要組成部分是行和列。為了操作這些信息,SourceGrid提供了2個屬性: 返回RowInfoCollection類型的集合,該集合是類RowInfo的條帶。 Columns—返回類型為ColumnInfoCollection的集合,該集合是列info類的列表。 這些是RowInfo類的一些屬性:高度,頂部,底部,索引,標簽。這些是代替ColumnInfo類的屬性:Width, Left, Right, Index, Tag。 有許多方法來操作行和列: 隱藏,復制Codegrid1.Redim (2, 2); 隱藏,Codegrid1副本。RowsCount = 2; grid1。ColumnsCount = 2; 隱藏,復制Codegrid1.Rows.Insert (0); grid1.Rows.Insert (1); grid1.Columns.Insert (0); grid1.Columns.Insert (1); 這三個示例執行相同的任務,即創建一個兩行兩列的表。 要更改行或列的寬度或高度,可以使用以下代碼: 隱藏,復制Code
grid1.Rows[0].Height = 100; grid1.Columns[0].Width = 100;
使用行和列的寬度和高度自動計算頂部、底部、左側和右側屬性。 面板 為了正確管理滾動條、固定的列和行以及許多其他細節,網格內部有一個面板結構,如下所示: 1) TopLeftPanel—保持固定的行和列單元格。 2) TopPanel—保持固定的行。 3) LeftPanel—保持固定列。 4) ScrollablePanel -保持所有不固定的單元格。 5) HScrollBar -水平滾動條 VScrollBar -垂直滾動條。 管理兩個滾動條之間的小空間的面板。 事件 鼠標和鍵盤事件可以與行為模型一起使用,也可以直接連接到網格上。 所有事件首先被觸發到面板,然后自動移動到GridVirtual和Grid控件。要使用這些事件,你可以寫這段代碼: 隱藏,復制Code
grid.MouseDown += new System.Windows.Forms.MouseEventHandler(
grid_MouseDown);
這也可以通過Visual Studio設計器完成。 查看項目SampleProject中的示例8以獲得詳細信息。 快捷菜單 網格有一個默認的ContextMenu,可以使用ContextMenuStyle屬性自定義。可以使用Grid.Selection將上下文菜單連接到選擇對象。ContextMenuItems,它將用於所有選定的單元格,否則,您可以將一個ContextMenu直接連接到一個特定的單元格。 查看項目SampleProject中的示例10以了解更多細節。 其他信息 關注和選擇 一個單元格可以選擇的可以有焦點。只有一個單元格可以有焦點,由網格的FocusCellPosition屬性標識,而不是選擇許多單元格。當一個單元格出現在網格的選擇對象中時被選中。 有焦點的單元格接收所有鼠標和鍵盤事件,而選中的單元格可以接收像復制/粘貼這樣的操作。 位置和范圍 項目SourceGrid中最常用的兩個對象是結構的位置和范圍。結構位置標識具有行和列的位置,而結構范圍標識從起始位置和結束位置分隔的一組單元格。 性能 為了優化這個控件的性能,在需要可視化很多單元格時使用GridVirtual控件,並總是嘗試在更多可能的單元格之間共享模型(DataModel, VisualModel, BehaviorModel)。 即使繪圖代碼仍然可以優化,網格的性能仍然非常好,特別是在滾動時。 有關網格性能的進一步信息,可以參考project SampleProject。 擴展 在項目SampleProject存在大量的例子和部分的代碼可以給意見或建議如何實現自定義網格,特別是在文件夾擴展存在一些網格提供的功能,如綁定數據集(數據表),數組和一個ArrayList。 截圖 如何 如何選擇整個行: 隱藏,復制Code
grid1.Rows[1].Select = true;
如何選擇所有的單元格: 隱藏,復制Code
grid1.Selection.AddRange(grid1.CompleteRange);
如何創建具有高級驗證規則的編輯器: 隱藏,復制Code
grid1[0,0] = new SourceGrid2.Cells.Real.Cell(2, typeof(int)); grid1[0,0].DataModel.MinimumValue = 2; grid1[0,0].DataModel.MaximumValue = 8; grid1[0,0].DataModel.DefaultValue = null; grid1[0,0].DataModel.AllowNull = true;
如何創建一個ComboBox編輯器來顯示與實際使用值不同的值,在本例中顯示的是字符串,而實際值是雙值。 隱藏,復制Code
double[] l_RealValues = new double[]{0.0,0.5,1.0}; SourceGrid2.DataModels.EditorComboBox l_EditorCombo = new SourceGrid2.DataModels.EditorComboBox(typeof(double)); l_EditorCombo.StandardValues = l_RealValues; l_EditorCombo.StandardValuesExclusive = true; l_EditorCombo.AllowStringConversion = false; SourceLibrary.ComponentModel.Validator.ValueMapping l_Mapping = new SourceLibrary.ComponentModel.Validator.ValueMapping(); l_Mapping.ValueList = l_RealValues; l_Mapping.DisplayStringList = new string[]{"Zero", "One Half", "One"}; l_Mapping.BindValidator(l_EditorCombo); grid1[0,0] = new SourceGrid2.Cells.Real.Cell(0.5, l_EditorCombo);
特性 SourceGrid可以做什么: 可以自定義每個單元格的圖形外觀、編輯器類型和行為(光標、工具提示文本、上下文菜單…)。 本機支持與TypeConverter或UITypeEditor關聯的所有數據類型。 任何。net控件都可以像編輯器一樣使用,只需幾行代碼。 您可以插入、刪除和移動行和列。 高度和寬度可以為每一列和每一行單獨定制,或者可以根據單元格的內容自動計算。 支持RowSpan和ColumnSpan的特性,以聯合更多的細胞。 支持自動復制粘貼操作。 本機支持列排序。 你可以常e列和行的寬度和高度。 在每個單元格中都可以自定義圖像以及文本和圖像的對齊方式。 支持多行和WordWrap文本。 支持HTML導出。 與一些擴展支持數據綁定特性。 支持用於綁定任何類型的數據源的虛擬單元格。 …什么是不能做的 SourceGrid沒有設計器,所有的工作都應該用代碼來完成。 沒有印刷的支持。 改變SourceGrid代碼 它允許改變,重新編譯和分發控制SourceGrid供私人和商業使用,我只要求在頁面的結尾保留版權說明。 我建議更改文件SourceGrid2。snk帶有個性化版本,不存在與不同版本兼容的問題的控件。進一步信息請咨詢MSDN: http://msdn.microsoft.com/library/default.asp? url=/library/en-us/cptutorials/html/_4余下a_shared_component.asp 未來的發展 繪圖代碼的增強。 支持屏蔽編輯文本框。 已知問題 沒有削減支持。 編輯器NumericUpDown與單元格沒有正確對齊。 Shift鍵不能與箭頭鍵一起工作,而且標題單元格仍然存在一些問題。 以前的版本 SourceGrid的版本2引入了許多更改,不可能列出所有更改。使用的方式非常相似,但是轉換用以前版本編寫的代碼並不簡單。 以下是一些建議: 網格的主要特性與ICellVirtual接口一起工作,不再與Cell類一起工作。這個接口只包含必要的方法,因此比較差。之前的代碼是: 隱藏,復制Codegrid[0,0] = new SourceGrid.Cell("Ciao"); 網格(0,0)。背景色= Color.White; 現在應該轉化了 隱藏,CodeSourceGrid2.Cells.Real副本。細胞l_Cell = 新SourceGrid2.Cells.Real.Cell(“再見”); l_Cell。背景色= Color.White; 網格(0,0)= l_Cell; 在以前的版本中,基單元格是從cell類識別出來的,而現在是接口ICellVirtual,該類的主要變化是不包含關於位置(行和列)的信息。 以前使用單元格類型的網格的許多方法現在使用位置類型,但是可以使用方法grid . getcell提取給定結構位置的接口ICellVirtual(然后轉換為更具體的接口) 現在,網格本地支持屬性BorderStyle,從而能夠消除之前引入邊框所必需的最終面板。 所有最初綁定到單元格事件的代碼現在必須在一個行為模型中移動,你可以使用例如sourcegrid . behaviormodels . customevents。 選擇對象不再是單元格的集合,而是范圍的集合。 通過插入行和列對象,首先應該在行和列上工作的代碼現在變得更簡單了,除了許多以前在網格中的方法現在都在RowInfoCollection、RowInfo、ColumnInfoCollection或ColumnInfo類中。 對象CellsContainer不再存在,即使邏輯上被面板替換,更多的commons會直接鏈接到網格,因此之前使用CellsContainer的代碼現在可以直接使用網格控件。 舊的對象ICellModel現在是對象IDataModel,而對象VisualProperties現在變成了IVisualModel。 類CellControl現在還不受支持,以后再引入時再考慮。 歷史 2.0.3.0(2004年3月25日) 移動和審查到SourceLibrary項目控件ComboBoxEx和TextBoxButton。 2.0.2.1(2004年3月24日) 修正了距離類的錯誤。當添加或刪除行時,ColumnSpan和RowsSpan信息不會被保留。 2.0.2.0(2004年3月23日) 修正了ColumnHeader排序時不使用FixedRows的錯誤 2.0.1.0(2004年3月23日) 將接口划分為IDataModel,並部分轉移到sourcelibrly . componentmodel . validator。 重命名方法StringToObject為StringToValue, ObjectToString為ValueToString。 現在,為了防止編輯一個組合框編輯器的文本框,您必須使用屬性AllowStringConversion = false。StandardValuesExclusive屬性允許只插入StandardValueList中存在的值。 將方法SupportStringConversion重命名為IsStringConversionSupported()。 刪除方法ExportValue和ImportValue。 現在使用文本框類型控件作為文本框。 增加了編輯器editortextbox數值用於輸入字符驗證數值數據類型。 AutoSize方法的標題單元格現在添加一些額外的空間排序圖標。 添加屬性Grid.Columns[0]。AutoSizeMode和Grid.Rows[0]。AutoSizeMode用於防止特定列/行的自動調整和拉伸。 Grid.Selection添加屬性。SelectedRows Grid.Selection。返回選定行或列的數組的SelectedColumns。 為單元格和行為模型添加方法oneditstart和OnEditEnded,在編輯開始和結束時調用。 IDataModel重命名方法。StartEdit到InternalStartEdit和EndEdit到InternalEndEdit因為這些只是內部方法,開始或結束編輯調用單元格。StartEdit / Cell.EndEdit。 重命名方法模型。GetDisplayString DataModel.ValueToDisplayString。 為單元格類型和編輯器添加了許多示例(參見示例3)。 修正了在調用AutoSize時沒有行或列的錯誤。 修正了SetFocusCell沒有將焦點放在網格中的錯誤。 修正了編輯模式下鼠標向下的錯誤。 2.0.0.0(2004年3月15日) 2.0版本的第一個版本 許可證(bsd風格的) .NET(c#)網格控件 版權所有(c) 2004, Davide Icardi 保留所有權利。 以源代碼和二進制形式(帶或不帶)重新分發和使用 有下列條件的,可以修改 滿足: 重新發布的源代碼必須保留上述版權 聲明、本條款及以下免責聲明。 以二進制形式重新分發必須重現上述內容 版權聲明,這個列表的條件以及其后的免責聲明 在提供的文檔和/或其他材料 分布。 請不要填寫該組織的名稱或其名稱 貢獻者可能被用來支持或推廣來自 本軟件沒有特定的事先書面許可。 本軟件由版權所有者和貢獻者提供 “是”,任何明示或默示保證,包括但不 限於適銷性和適合的隱含保證 特殊目的被否認。在任何事件應當版權 所有人或貢獻者對任何直接、間接、偶然、 特殊的、懲罰性的或間接的損失(包括但不包括在內) 限於采購替代商品或服務;損失的使用, 數據,或者利潤;或業務中斷)然而,任何引起的 責任理論,無論是在合同,嚴格責任,或侵權 (包括疏忽或其他)在使用過程中產生的任何方式 ,即使被告知有可能造成這種損壞。 本文轉載於:http://www.diyabc.com/frontweb/news354.html