zoukankan      html  css  js  c++  java
  • SourceGrid zt

    SourceGrid介绍和使用及实例举例

    先上图,来一个简单演示:
     

    SourceGrid就是一个用于数据显示的表格控件,这个控件比c#自带的 DataGridView要强大很多,先不说他的原理,只说他的功能,可以实现各种自定义样式、嵌入各种控件,如checkbox、Combobox、 Button、超级链接、其他自定义控件等等,另外他不依赖于数据源显示,可以随意控制其显示的单元格;

    一,使用方法:
        1.1 首先去下载一个SourceGrid控件库,这个是开源控件,下载好后整理一套动态库,放入你的项目里,主要有以下几个:
        DevAge.Core.dll      //辅助核心
        DevAge.Windows.Forms.dll  //包装了用于winform里的某些控件的定义
        log4net.dll  //日志库
        SourceGrid.dll             //核心库
        SourceGrid.Extensions.dll  //扩展库
       
        1.2 新建一个winform工程,将这些类库放入debug目录下,然后在工具箱点右键,选择项,点浏览,选择SourceGrid.dll,加入到工具箱;
        然后像使用其他控件一样,拖到窗体上;

    技术互动


    二,代码的编写;
        SourceGrid一般都是以纯代码实现;
       
        2.1首先我们建一个用于数据显示的对象:
        public class Student
        {
            public string Name { get; set; }
            public string Gender { get; set; }
            public DateTime Birth { get; set; }
            public int Fee { get; set; }
        }

       2.2 增加数据:
        定义私有的实例变量:
        private List<Student> students = null;
        在窗体构造函数里初始化此变量:
               students = new List<Student>()
                {
                    new Student(){ Name="张三",Gender="1",Birth=DateTime.Parse("1989-1-1"),Fee = 2500},
                    new Student(){ Name="李四",Gender="0",Birth=DateTime.Parse("1989-12-10"),Fee = 2200},
                    new Student(){ Name="王五",Gender="0",Birth=DateTime.Parse("1989-4-4"),Fee = 2800}
                };
      2.3 在SourceGrid里显示,并统计所收学费总和;
        

    2.3.1  定义方法GetData()
         首先初始化列:
                SourceGrid.Grid grid = grid1;
                grid.BorderStyle = BorderStyle.FixedSingle;
                grid.FixedRows = 1;
                grid.FixedColumns = 1;
               
                //初始化列
                int gridColumnsCount = 5;//设定列数
                int gridRowsCount = students.Count+2;//设定行数
                int gridWith = this.Width - 20;//设定宽度为当前窗体宽度
                int[] colsWidth = { 20, 160, 160, 100, 100 };//每列的宽度
                string[] colsText = { "", "姓名", "性别", "生日", "已收学费" };//每列的标题

                grid.Rows.Insert(0);
                grid.ColumnsCount = gridColumnsCount;
                grid.Width = gridWith;
             
                int otherColsWidth = 0;
                for (int i = 0; i < 5; i++)
                {
                    SourceGrid.Cells.ColumnHeader head = new SourceGrid.Cells.ColumnHeader(colsText);
                    head.AutomaticSortEnabled = false;//禁止排序
                    if (i != grid.ColumnsCount - 1)
                    {
                        grid.Columns.Width = colsWidth;
                        otherColsWidth += colsWidth;
                    }
                    else
                        grid.Columns.Width = grid1.Width - otherColsWidth - 2 * i;//让最后一列铺满整个Grid
                    grid[0, i] = head;              
                }

          其次,初始化行:
         //初始化所有单元格
                int rowsReadOnly = gridColumnsCount - 2;//设置某行为只读
                for (int i = 0; i <gridRowsCount; i++)
                {
                    int r = grid.RowsCount;
                    grid.Rows.Insert(r);
                    for (int j = 1; j < gridColumnsCount;j++ )
                    {
                        grid[r, j] = new SourceGrid.Cells.Cell("", typeof(string));
                        if (i == rowsReadOnly)
                        {
                            grid[r, j].Editor = null;
                        }
                    }
                }
         填充数据:
              //赋值
                int sum = 0;
                for (int i = 0; i < students.Count; i++)
                {
                    int r = i + 1;
                    grid[r, 1] .Value=students.Name;
                    grid[r, 2] .Value= students.Gender;
                    grid[r, 3] =new SourceGrid.Cells.Cell(students.Birth, typeof(DateTime));
                    grid[r, 4] =new SourceGrid.Cells.Cell(students.Fee, typeof(int));
                    sum += students.Fee;
                }
                //设置倒数第二行的高度,直接将最后一行挤到最底部;
                grid.Rows[grid1.Rows.Count - 2].Height = grid1.Height - grid1.Rows[0].Height * (grid1.RowsCount) + 10;
               
                //设置倒数第一行的内容
                grid[grid.Rows.Count - 1, 1] = new SourceGrid.Cells.Cell("总计:", typeof(string));
                grid[grid.Rows.Count - 1, 4] = new SourceGrid.Cells.Cell(sum.ToString() + "圆整", typeof(string));

    摘录一段网上的描述:
    每个单元格由 4 个基本部分组成, 它们基于改进的“模式-外观-控制器(Model-View-Controller)”模型�
    模式(Model): 模式是管理单元格取值的类, 它包含相关的取值或属性, 并且与其他组件相联系. 
    外观(View) : 外观是绘制单元格, 并包含可视属性的类. 
    控制器(Controller) : 控制器是提供单元格行为的类.  编辑器(Editor) :
    编辑器是定制单元格的编辑器的类.  这种划分为代码提供了很大的弹性和可重用性, 可节约时间, 为每种定制类型提供可靠的基础。  
    为了较通用的要求�一些类已经被准备和配置, 但是, 可能会需要以某些代码行建立个性化单元格。

    简单的理解:
    因此,如果想改变外观,就选择或者自定义VIEW,如果想要增加事件、行为,则要选择或者自定义控制器,如果想进去用合适的控件编辑,则要选择或自定义编辑器;

    而单元格里面放的是个对象,这个对象可以是普通的单元格、也可以是按钮、也可以是其他类型,等等;

    具体的描述性文档可以参照网上的详细介绍:
    http://wenku.baidu.com/view/9bde88eb0975f46527d3e156.html

    下面给大家列举一个实用的例子
    先上图:

    技术互动
     

    实现的功能:
    1,自定义列,最后一列铺满整个grid;
    2,第0列放一个按钮,单击此按钮可以弹出窗口,选择新窗口的某条记录,记录的结果显示在此行相应的单元格里;
    3,性别的选择为下拉列表,且只能是枚举里的值;
    4,生日的选择只能为日期,可以弹出日期选择框选择;
    5,当前的行用满了,则可以右键增加一行;
    6,可以删除选择的行;
    相应的代码:
    定义几个实例变量:
            private int gridRowsCount = 10;//设定行数
            private int gridColumnsCount = 5;//设定列数
            private int[] colsWidth = { 20, 160, 160, 100, 100 };//每列的宽度
            private string[] colsText = { "", "姓名", "性别", "生日", "已收学费" };//每列的标题

    定义一个初始化GRID方法,基本都有注解
    private void GetGrid()
            {
                SourceGrid.Grid grid = grid1;
                #region 初始化grid
                grid.Redim(gridRowsCount, gridColumnsCount);
                //选择模式为行
                grid.SelectionMode = SourceGrid.GridSelectionMode.Row;
                //设置固定列和固定行
                grid.FixedColumns = 1;
                grid.FixedRows = 1;
                //初始化列,最后一列铺满整个grid
                for (int i = 0,otherColsWidth = 0; i < gridColumnsCount; i++)
                {
                    SourceGrid.Cells.ColumnHeader head = new SourceGrid.Cells.ColumnHeader(colsText[i]);
                    head.AutomaticSortEnabled = false;//取消自动排序
                    if (i != grid.ColumnsCount - 1)//不是最后一列
                    {
                        grid.Columns[i].Width = colsWidth[i];
                        otherColsWidth += colsWidth[i];
                    }
                    else //设置最后一列铺满整个grid
                        grid.Columns[i].Width = grid1.Width - otherColsWidth - 2 * i;
                    grid[0, i] = head;
                }
                //初始化行
                for (int i = 1; i < gridRowsCount; i++)
                {
                    IniOneRow(i);
                }
                #endregion
            }
    其中有个初始化某行,代码见下:

    /// <summary>
            /// 初始化一行
            /// </summary>
            /// <param name="rowIndex"></param>
            private void IniOneRow(int rowIndex)
            {
                SourceGrid.Grid grid = grid1;
                //单击控制器
                SourceGrid.Cells.Controllers.Button buttonClickEvent = new SourceGrid.Cells.Controllers.Button();
                buttonClickEvent.Executed += new EventHandler(CellButton_Click);
                //下拉框 暂时没用到
                //SourceGrid.Cells.Editors.ComboBox cbEditor = new SourceGrid.Cells.Editors.ComboBox(typeof(EnumGender));
                //cbEditor.StandardValues = new EnumGender[] { EnumGender.男, EnumGender.女 };
                //cbEditor.EditableMode = SourceGrid.EditableMode.Focus | SourceGrid.EditableMode.SingleClick | SourceGrid.EditableMode.AnyKey;
                //日期编辑器
                SourceGrid.Cells.Editors.TextBoxUITypeEditor editorDateTime = new SourceGrid.Cells.Editors.TextBoxUITypeEditor(typeof(DateTime));
                PopupMenu menuController = new PopupMenu(this);
                for (int j = 0; j < gridColumnsCount; j++)
                {
                    if (j == 0)
                    {
                        //单元格设置为按钮
                        grid[rowIndex, j] = new SourceGrid.Cells.Button("…");
                        //存放某些必须的信息,如关键字
                        grid[rowIndex, j].Tag = rowIndex;
                        //为按钮增加事件
                        grid[rowIndex, j].AddController(buttonClickEvent);
                    }
                    else if (j == 2)
                    {
                        //设置为枚举类型,激活之后将会显示为下拉框
                        grid[rowIndex, j] = new SourceGrid.Cells.Cell(null, typeof(EnumGender));
                        //grid[i, j].Editor = cbEditor;
                        //grid[i, j].View = SourceGrid.Cells.Views.ComboBox.Default;
                    }
                    else if (j == 3)//日期格式,控制其 显示和输入
                    {
                        grid[rowIndex, j] = new SourceGrid.Cells.Cell("", typeof(DateTime));
                        grid1[rowIndex, j].Editor = editorDateTime;
                    }
                    else
                        grid[rowIndex, j] = new SourceGrid.Cells.Cell("", typeof(string));
                    //设置每行的激活编辑方式
                    if (grid[rowIndex, j].Editor!=null)
                        grid[rowIndex, j].Editor.EditableMode = SourceGrid.EditableMode.Focus | SourceGrid.EditableMode.SingleClick;
                        //grid[rowIndex, j].Editor.EditableMode = SourceGrid.EditableMode.Focus | SourceGrid.EditableMode.SingleClick | SourceGrid.EditableMode.AnyKey;
                    //为每个行增加右键菜单
                    grid[rowIndex, j].AddController(menuController);

                }
            }

    这里稍微有点复杂:
    1,了解按钮控件如何放单元格里;
    2,按钮的事件如何关联
    2,了解枚举类型如何处理;
    3,如何增加菜单。对于菜单部分,还有部分代码如下:

    本帖最后由 繁华都市 于 2013-1-11 10:57 编辑


    /// <summary>
            /// 按钮单击事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void CellButton_Click(object sender, EventArgs e)
            {
                SourceGrid.CellContext context = (SourceGrid.CellContext)sender;
                SourceGrid.Cells.Button btnCell = (SourceGrid.Cells.Button)context.Cell;
                string id = btnCell.Tag.ToString();
                MessageBox.Show(id);
                Student stu = new Student() { Name = "张三", Gender = "1", Birth = DateTime.Parse("1991-1-1"), Fee = 2500 };
                EnumGender sGender = stu.Gender == "1" ? EnumGender.男 : EnumGender.女;
                int currenRow = btnCell.Row.Index;
                grid1[currenRow, 1].Value = stu.Name;
                grid1[currenRow, 2].Value = sGender;
                grid1[currenRow, 3].Value = stu.Birth;
                grid1[currenRow, 4].Value = stu.Fee;
            }

    下面是菜单的两个操作定义:
      /// <summary>
            /// 新增一行
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void Menu1_Click(object sender, EventArgs e)
            {
                int i = grid1.RowsCount;
                grid1.Rows.Insert(i);
                IniOneRow(i);
            }
            /// <summary>
            /// 删除一行
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void Menu2_Click(object sender, EventArgs e)
            {
                //TODO Your code here
                int[] rowsIndex = grid1.Selection.GetSelectionRegion().GetRowsIndex();
                SourceGrid.RowInfo[] rows = new SourceGrid.RowInfo[rowsIndex.Length];
                for (int i = 0; i < rows.Length; i++)
                    rows = grid1.Rows[rowsIndex【i】];

       foreach (SourceGrid.RowInfo r in rows)
                    grid1.Rows.Remove(r.Index);
                if (grid1.RowsCount > 1)
                    grid1.Selection.FocusRow(1);
            }

    菜单控制器的定义如下:
      public class PopupMenu : SourceGrid.Cells.Controllers.ControllerBase
        {
            ContextMenu menu = new ContextMenu();
            private FormGridEdit mFrm;
            public PopupMenu(FormGridEdit frm)
            {
                mFrm = frm;
                menu.MenuItems.Add("新增一行", new EventHandler(mFrm.Menu1_Click));
                menu.MenuItems.Add("删除选中的行", new EventHandler(mFrm.Menu2_Click));
            }
            public override void OnMouseUp(SourceGrid.CellContext sender, MouseEventArgs e)
            {
                base.OnMouseUp(sender, e);
                if (e.Button == MouseButtons.Right)
                    menu.Show(sender.Grid, new Point(e.X, e.Y));
            }
          
        }

    性别的枚举:
        /// <summary>
        /// 枚举,为下拉框准备
        /// </summary>
        public enum EnumGender
        {
            男,
            女,
            无
        }

  • 相关阅读:
    爬取网易云音乐歌手和id
    【兼容调试】cffi library '_openssl' has no function, constant or global variable named 'Cryptography_HAS
    python如何去掉字符串‘xa0’
    python 中json和字符串互相转换
    vip视频播放
    一行Python代码画心型
    Java语言编写MD5加密方法,Jmeter如何给字符串MD5加密
    转载:oracle RAC集群启动和关闭
    转载:oracle 11g ADG实施手册(亲测,已成功部署多次)
    如何上传本地文件到github又如何删除自己的github仓库
  • 原文地址:https://www.cnblogs.com/zeroone/p/3223416.html
Copyright © 2011-2022 走看看