开源c#网格控件

介绍 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

原文地址:https://www.cnblogs.com/Dincat/p/13443543.html