2012-07-27 31 views
4

我正在尝试创建一个DataGridView列,其中包含Radiobuttons。我一直在关注this MSDN文章。使用Radiobutton列创建DataGridView

尽管我已经改变了教程中的代码来编写我自己的类,但它不能按预期工作。事情是我不完全确定我错过了什么。编译时不会出错。但它显示为复选框而不是Radibuttons。 enter image description here

我附加了Visual Studio项目here。对于那些不确定下载未知附件的人,下面是我写的3个课程。

RadiobuttonColumn class。它继承了DataGridViewColumn类。

using System; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    class RadiobuttonColumn : DataGridViewColumn 
    { 
     public RadiobuttonColumn() 
      : base(new RadiobuttonCell()) 
     { 
     } 

     public override DataGridViewCell CellTemplate 
     { 
      get 
      { 
       return base.CellTemplate; 
      } 
      set 
      { 
       if (value != null && !value.GetType().IsAssignableFrom(typeof(RadiobuttonCell))) 
       { 
        throw new InvalidCastException("Must be a RadiobuttonCell"); 
       } 
      } 
     } 
    } 
} 

修订RadiobuttonCell类继承DataGridViewCell类。


using System; 
using System.Windows.Forms; 
using System.Drawing; 

namespace DataGridView_Radiobutton_column 
{ 
    public class RadiobuttonCell : DataGridViewCell 
    { 
     public RadiobuttonCell() 
      : base() 
     { 
     } 

     public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) 
     { 
      base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); 
      RadiobuttonEditingControl rdb = DataGridView.EditingControl as RadiobuttonEditingControl; 
      if (this.Value == null) 
      { 
       rdb.Checked = false; 
      } 
      else 
      { 
       rdb.Checked = (Boolean)this.Value; 
      } 
     } 

     public override Type EditType 
     { 
      get 
      { 
       return typeof(RadiobuttonEditingControl); 
      } 
     } 

     public override Type ValueType 
     { 
      get 
      { 
       return typeof(Boolean); 
      } 
     } 

     public override object DefaultNewRowValue 
     { 
      get 
      { 
       return false; 
      } 
     } 

     protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) 
     { 
      base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); 


      Rectangle rectRadioButton = default(Rectangle); 

      rectRadioButton.Width = 14; 
      rectRadioButton.Height = 14; 
      rectRadioButton.X = cellBounds.X + (cellBounds.Width - rectRadioButton.Width)/2; 
      rectRadioButton.Y = cellBounds.Y + (cellBounds.Height - rectRadioButton.Height)/2; 

      ControlPaint.DrawRadioButton(graphics, rectRadioButton, ButtonState.Normal); 
     } 
    } 
} 

RadiobuttonEditingControl类继承的RadioButton类并实现IDataGridViewEditingControl接口的方法。

using System; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    class RadiobuttonEditingControl : RadioButton, IDataGridViewEditingControl 
    { 
     DataGridView dataGridView; 
     private bool valueChanged = false; 
     int rowIndex; 

     public RadiobuttonEditingControl() 
     { 
      this.Checked = false; 
     } 

     public object EditingControlFormattedValue 
     { 
      get 
      { 
       return this.Checked = true; 
      } 
      set 
      { 
       this.Checked = false; 
      } 
     } 

     public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) 
     { 
      return EditingControlFormattedValue; 
     } 

     public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) 
     { 
     } 

     public int EditingControlRowIndex 
     { 
      get 
      { 
       return rowIndex; 
      } 
      set 
      { 
       rowIndex = value; 
      } 
     } 

     public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey) 
     { 
      switch (key & Keys.KeyCode) 
      { 
       case Keys.Space: 
        return true; 
       default: 
        return !dataGridViewWantsInputKey; 
      } 
     } 

     public void PrepareEditingControlForEdit(bool selectAll) 
     { 
     } 

     public bool RepositionEditingControlOnValueChange 
     { 
      get 
      { 
       return false; 
      } 
     } 

     public DataGridView EditingControlDataGridView 
     { 
      get 
      { 
       return dataGridView; 
      } 
      set 
      { 
       dataGridView = value; 
      } 
     } 

     public bool EditingControlValueChanged 
     { 
      get 
      { 
       return valueChanged; 
      } 
      set 
      { 
       valueChanged = value; 
      } 
     } 

     public Cursor EditingPanelCursor 
     { 
      get 
      { 
       return base.Cursor; 
      } 
     } 

     protected override void OnCheckedChanged(EventArgs eventArgs) 
     { 
      valueChanged = true; 
      this.EditingControlDataGridView.NotifyCurrentCellDirty(true); 
      base.Checked = false; 
     } 
    } 
} 

如果有人可以看看这个,我指向正确的方向,以什么样的变化,应在代码来完成,我会很感激。

谢谢。

回答

2

当您开始编辑单元格时会发生什么?它变成一个单选按钮。

这是因为您从复选框单元格派生出来,该复选框单元格将其自身描绘为复选框。

DGV不是控件的网格。这是一个盒子的网格,看起来像控件,直到用户试图编辑单元格。此时,DGV将单元格的(唯一的)编辑控件移动到位置,并使用户可以看到它进行交互。

您将不得不从基础DataGridViewCell类派生并实现所有绘画代码。

示例代码不必这样做,因为文本框单元格知道如何绘制文本。

更新

ControlPaint类可以帮助你。

+0

谢谢Tergiver的回应。按照您的指示,我已经更改了'RadiobuttonCell'类。请在我原来的帖子中查看更新的代码。我继承了'DataGridViewCell'类,并且重写了'Paint'方法。不过,我正面临一个小问题。 DataGridView的背景看起来是透明的。 [Here](http://i.imgur.com/63Df7.png)是一个截图。我怎样才能克服这个问题? – Isuru 2012-07-28 09:40:54

+0

@ nK0de你也必须画背景。使用单元格的样式来确定单元格是否被选中。我认为你可以使用'graphics.Clear(cellStyle.BackColor:cellStyle.SelectedColor)'。您还希望根据单元格的当前值绘制单选按钮。 – Tergiver 2012-07-29 01:16:56

+0

@ nK0de另外,绘图是分阶段进行的,因此您想使用paintParts参数来确定应该绘制哪个部分。 – Tergiver 2012-07-29 01:18:23