当前位置: 移动技术网 > IT编程>开发语言>c# > C#自定义DataGridViewColumn显示TreeView

C#自定义DataGridViewColumn显示TreeView

2019年07月18日  | 移动技术网IT编程  | 我要评论

我们可以自定义datagridview的datagridviewcolumn来实现自定义的列,下面介绍一下如何通过扩展datagridviewcolumn来实现一个treeviewcolumn

1.treeviewcolumn类

 treeviewcolumn继承自datagridviewcolumn,为了动态给treeviewcolumn传入一个treeview,这里暴露出一个公共属性_root,可以绑定一个初始化的treeview. 另外需要重写datagridcell类型的celltemplate,这里返还一个treeviewcell(需要自定义) 

 /// <summary>
  /// host treeview in datagridview cell
  /// </summary>
  public class treeviewcolumn : datagridviewcolumn
  {
   public treeviewcolumn()
    : base(new treeviewcell())
   {
   }
   [description("set treeview root in datagridview cell"), category("treeview")]
   public treeview _root
   {
    get{return roots.tree;}
    set{roots.tree=value;}
   }
   public override datagridviewcell celltemplate
   {
    get
    {
     return base.celltemplate;
    }
    set
    {
     // ensure that the cell used for the template is a treeviewcell.
     if (value != null &&
      !value.gettype().isassignablefrom(typeof(treeviewcell)))
     {
      throw new invalidcastexception("must be a treeviewcell");
     }
     base.celltemplate = value;
    }
   }
  } 

2.treeviewcell类

    上面treeviewcolumn重写了celltemplate,返回的就是自定义的treeviewcell,这里就是具体实现其逻辑。一般来说选择树控件的节点后,返回的是一个文本信息,是文本类型,可以继承datagridviewtextboxcell,并重写initializeeditingcontrol来进行自定义的datagridview.editingcontrol (编辑控件)。

 public class treeviewcell : datagridviewtextboxcell
  {
   public treeviewcell()
    : base()
   {
    //初始设置
   }
   public override void initializeeditingcontrol(int rowindex, object
    initialformattedvalue, datagridviewcellstyle datagridviewcellstyle)
   {
    // set the value of the editing control to the current cell value.
    base.initializeeditingcontrol(rowindex, initialformattedvalue,
     datagridviewcellstyle);
    treevieweditingcontrol ctl =
     datagridview.editingcontrol as treevieweditingcontrol;
    // use the default row value when value property is null.
    if (this.value == null)
    {
     ctl.selectednode =new treenode( this.defaultnewrowvalue.tostring());
    }
    else
    {
     ctl.selectednode = new treenode(this.value.tostring());
    }
   }
   public override type edittype
   {
    get
    {
     // return the type of the editing control that calendarcell uses.
     return typeof(treevieweditingcontrol);
    }
   }
   public override type valuetype
   {
    get
    {
     // return the type of the value that calendarcell contains.
     return typeof(string);
    }
   }
   public override object defaultnewrowvalue
   {
    get
    {
     // use the current date and time as the default value.
     return "";
    }
   }
  } 

3.treevieweditingcontrol类

  treevieweditingcontrol为编辑控件,当用户编辑treeviewcell时,显示的为树编辑控件,需要继承treeview,同时实现idatagridvieweditingcontrol接口,实现以下方法:

 public class treevieweditingcontrol : treeview, idatagridvieweditingcontrol
  {
   datagridview datagridview;
   private bool valuechanged = false;
   int rowindex;
   public treevieweditingcontrol()
   {
    try
    {
     //必须加roots.tree.nodes[].clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆
     this.nodes.add(roots.tree.nodes[].clone() as treenode);
     this.selectednode = this.nodes[];
    }
    catch (exception ex)
    {
     messagebox.show(ex.message);
    }
   }
   // implements the idatagridvieweditingcontrol.editingcontrolformattedvalue 
   // property.
   public object editingcontrolformattedvalue
   {
    get
    {
     return this.selectednode.text;
    }
    set
    {
     if (value is string)
     {
      try
      {
       // this will throw an exception of the string is 
       // null, empty, or not in the format of a date.
       this.selectednode = new treenode((string)value);
      }
      catch
      {
       // in the case of an exception, just use the 
       // default value so we're not left with a null
       // value.
       this.selectednode = new treenode("");
      }
     }
    }
   }
   // implements the 
   // idatagridvieweditingcontrol.geteditingcontrolformattedvalue method.
   public object geteditingcontrolformattedvalue(
    datagridviewdataerrorcontexts context)
   {
    return editingcontrolformattedvalue;
   }
   // implements the 
   // idatagridvieweditingcontrol.applycellstyletoeditingcontrol method.
   public void applycellstyletoeditingcontrol(
    datagridviewcellstyle datagridviewcellstyle)
   {
    this.font = datagridviewcellstyle.font;
    this.forecolor = datagridviewcellstyle.forecolor;
    this.backcolor = datagridviewcellstyle.backcolor;
   }
   // implements the idatagridvieweditingcontrol.editingcontrolrowindex 
   // property.
   public int editingcontrolrowindex
   {
    get
    {
     return rowindex;
    }
    set
    {
     rowindex = value;
    }
   }
   // implements the idatagridvieweditingcontrol.editingcontrolwantsinputkey 
   // method.
   public bool editingcontrolwantsinputkey(
    keys key, bool datagridviewwantsinputkey)
   {
    // let the treeviewpicker handle the keys listed.
    switch (key & keys.keycode)
    {
     case keys.left:
     case keys.up:
     case keys.down:
     case keys.right:
     case keys.home:
     case keys.end:
     case keys.pagedown:
     case keys.pageup:
      return true;
     default:
      return !datagridviewwantsinputkey;
    }
   }
   // implements the idatagridvieweditingcontrol.prepareeditingcontrolforedit 
   // method.
   public void prepareeditingcontrolforedit(bool selectall)
   {
    // no preparation needs to be done.
   }
   // implements the idatagridvieweditingcontrol
   // .repositioneditingcontrolonvaluechange property.
   public bool repositioneditingcontrolonvaluechange
   {
    get
    {
     return false;
    }
   }
   // implements the idatagridvieweditingcontrol
   // .editingcontroldatagridview property.
   public datagridview editingcontroldatagridview
   {
    get
    {
     return datagridview;
    }
    set
    {
     datagridview = value;
    }
   }
   // implements the idatagridvieweditingcontrol
   // .editingcontrolvaluechanged property.
   public bool editingcontrolvaluechanged
   {
    get
    {
     return valuechanged;
    }
    set
    {
     valuechanged = value;
    }
   }
   // implements the idatagridvieweditingcontrol
   // .editingpanelcursor property.
   public cursor editingpanelcursor
   {
    get
    {
     return base.cursor;
    }
   }
   protected override void onafterexpand(treevieweventargs e)
   {
    base.onafterexpand(e);
    this.datagridview.columns[this.datagridview.currentcell.columnindex].width = this.width+;
    this.datagridview.rows[this.datagridview.currentcell.rowindex].height = this.height+;
   }
   protected override void onafterselect(treevieweventargs e)
   {
    // notify the datagridview that the contents of the cell
    // have changed.
    valuechanged = true;
    this.editingcontroldatagridview.notifycurrentcelldirty(true);
    base.onafterselect(e);
   }
  } 

  为了在不同类之间传递参数,定义一个全局静态类:

 /// <summary>
  /// 静态类的静态属性,用于在不同class间传递参数
  /// </summary>
  public static class roots
  {
   //从前台绑定树
  public static treeview tree = null;
  }

完整代码为:

 using system;
 using system.collections.generic;
 using system.linq;
 using system.text;
 using system.windows.forms;
 using system.componentmodel;
 namespace host_controls_in_windows_forms_datagridview_cells
 {
  /// <summary>
  /// 静态类的静态属性,用于在不同class间传递参数
  /// </summary>
  public static class roots
  {
   //从前台绑定树
   public static treeview tree = null;
  }
  /// <summary>
  /// host treeview in datagridview cell
  /// </summary>
  public class treeviewcolumn : datagridviewcolumn
  {
   public treeviewcolumn()
    : base(new treeviewcell())
   {
   }
   [description("set treeview root in datagridview cell"), category("treeview")]
   public treeview _root
   {
    get{return roots.tree;}
    set{roots.tree=value;}
   }
   public override datagridviewcell celltemplate
   {
    get
    {
     return base.celltemplate;
    }
    set
    {
     // ensure that the cell used for the template is a treeviewcell.
     if (value != null &&
      !value.gettype().isassignablefrom(typeof(treeviewcell)))
     {
      throw new invalidcastexception("must be a treeviewcell");
     }
     base.celltemplate = value;
    }
   }
  }
  //----------------------------------------------------------------------
  public class treeviewcell : datagridviewtextboxcell
  {
   public treeviewcell()
    : base()
   {
    //初始设置
   }
   public override void initializeeditingcontrol(int rowindex, object
    initialformattedvalue, datagridviewcellstyle datagridviewcellstyle)
   {
    // set the value of the editing control to the current cell value.
    base.initializeeditingcontrol(rowindex, initialformattedvalue,
     datagridviewcellstyle);
    treevieweditingcontrol ctl =
     datagridview.editingcontrol as treevieweditingcontrol;
    // use the default row value when value property is null.
    if (this.value == null)
    {
     ctl.selectednode =new treenode( this.defaultnewrowvalue.tostring());
    }
    else
    {
     ctl.selectednode = new treenode(this.value.tostring());
    }
   }
   public override type edittype
   {
    get
    {
     // return the type of the editing control that calendarcell uses.
     return typeof(treevieweditingcontrol);
    }
   }
   public override type valuetype
   {
    get
    {
     // return the type of the value that calendarcell contains.
     return typeof(string);
    }
   }
   public override object defaultnewrowvalue
   {
    get
    {
     // use the current date and time as the default value.
     return "";
    }
   }
  }
  //-----------------------------------------------------------------
 public class treevieweditingcontrol : treeview, idatagridvieweditingcontrol
  {
   datagridview datagridview;
   private bool valuechanged = false;
   int rowindex;
   public treevieweditingcontrol()
   {
    try
    {
     //必须加roots.tree.nodes[].clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆
     this.nodes.add(roots.tree.nodes[].clone() as treenode);
     this.selectednode = this.nodes[];
    }
    catch (exception ex)
    {
     messagebox.show(ex.message);
    }
   }
   // implements the idatagridvieweditingcontrol.editingcontrolformattedvalue 
   // property.
   public object editingcontrolformattedvalue
   {
    get
    {
     return this.selectednode.text;
    }
    set
    {
     if (value is string)
     {
      try
      {
       // this will throw an exception of the string is 
       // null, empty, or not in the format of a date.
       this.selectednode = new treenode((string)value);
      }
      catch
      {
       // in the case of an exception, just use the 
       // default value so we're not left with a null
       // value.
       this.selectednode = new treenode("");
      }
     }
    }
   }
   // implements the 
   // idatagridvieweditingcontrol.geteditingcontrolformattedvalue method.
   public object geteditingcontrolformattedvalue(
    datagridviewdataerrorcontexts context)
   {
    return editingcontrolformattedvalue;
   }
   // implements the 
   // idatagridvieweditingcontrol.applycellstyletoeditingcontrol method.
   public void applycellstyletoeditingcontrol(
    datagridviewcellstyle datagridviewcellstyle)
   {
    this.font = datagridviewcellstyle.font;
    this.forecolor = datagridviewcellstyle.forecolor;
    this.backcolor = datagridviewcellstyle.backcolor;
   }
   // implements the idatagridvieweditingcontrol.editingcontrolrowindex 
   // property.
   public int editingcontrolrowindex
   {
    get
    {
     return rowindex;
    }
    set
    {
     rowindex = value;
    }
   }
   // implements the idatagridvieweditingcontrol.editingcontrolwantsinputkey 
   // method.
   public bool editingcontrolwantsinputkey(
    keys key, bool datagridviewwantsinputkey)
   {
    // let the treeviewpicker handle the keys listed.
    switch (key & keys.keycode)
    {
     case keys.left:
     case keys.up:
     case keys.down:
     case keys.right:
     case keys.home:
     case keys.end:
     case keys.pagedown:
     case keys.pageup:
      return true;
     default:
      return !datagridviewwantsinputkey;
    }
   }
   // implements the idatagridvieweditingcontrol.prepareeditingcontrolforedit 
   // method.
   public void prepareeditingcontrolforedit(bool selectall)
   {
    // no preparation needs to be done.
   }
   // implements the idatagridvieweditingcontrol
   // .repositioneditingcontrolonvaluechange property.
   public bool repositioneditingcontrolonvaluechange
   {
    get
    {
     return false;
    }
   }
   // implements the idatagridvieweditingcontrol
   // .editingcontroldatagridview property.
   public datagridview editingcontroldatagridview
   {
    get
    {
     return datagridview;
    }
    set
    {
     datagridview = value;
    }
   }
   // implements the idatagridvieweditingcontrol
   // .editingcontrolvaluechanged property.
   public bool editingcontrolvaluechanged
   {
    get
    {
     return valuechanged;
    }
    set
    {
     valuechanged = value;
    }
   }
   // implements the idatagridvieweditingcontrol
   // .editingpanelcursor property.
   public cursor editingpanelcursor
   {
    get
    {
     return base.cursor;
    }
   }
   protected override void onafterexpand(treevieweventargs e)
   {
    base.onafterexpand(e);
    this.datagridview.columns[this.datagridview.currentcell.columnindex].width = this.width+;
    this.datagridview.rows[this.datagridview.currentcell.rowindex].height = this.height+;
   }
   protected override void onafterselect(treevieweventargs e)
   {
    // notify the datagridview that the contents of the cell
    // have changed.
    valuechanged = true;
    this.editingcontroldatagridview.notifycurrentcelldirty(true);
    base.onafterselect(e);
   }
  }
 }

  当编辑无误后,可以在添加列的时候看到treeviewcolumn类型。此类型暴露出一个_root属性,可以绑定外部的一个带数据的treeview。

  运行代码,单击单元格,进入编辑状态,可以看到如下界面:

以上内容是小编给大家介绍的c#自定义datagridviewcolumn显示treeview 的全部叙述,希望大家喜欢。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网