2012-07-27 28 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