📄 datagridviewradiobuttoncell.cs
字号:
using System;
using System.Drawing;
using System.Globalization;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Diagnostics;
namespace DataGridViewRadioButtonElements
{
public class DataGridViewRadioButtonCell : DataGridViewComboBoxCell, IDataGridViewEditingCell
{
/// <summary>
/// Convenient enumeration using privately for calculating preferred cell sizes.
/// </summary>
private enum DataGridViewRadioButtonFreeDimension
{
Both,
Height,
Width
}
// 4 pixels of margin on the left and right of error icons
private const byte DATAGRIDVIEWRADIOBUTTONCELL_iconMarginWidth = 4;
// 4 pixels of margin on the top and bottom of error icons
private const byte DATAGRIDVIEWRADIOBUTTONCELL_iconMarginHeight = 4;
// all icons are 12 pixels wide by default
private const byte DATAGRIDVIEWRADIOBUTTONCELL_iconsWidth = 12;
// all icons are 11 pixels tall by default
private const byte DATAGRIDVIEWRADIOBUTTONCELL_iconsHeight = 11;
// default value of MaxDisplayedItems property
internal const int DATAGRIDVIEWRADIOBUTTONCELL_defaultMaxDisplayedItems = 3;
// blank pixels around each radio button entry
private const byte DATAGRIDVIEWRADIOBUTTONCELL_margin = 2;
// codes used for the mouseLocationCode static variable:
private const int DATAGRIDVIEWRADIOBUTTONCELL_mouseLocationGeneric = -3;
private const int DATAGRIDVIEWRADIOBUTTONCELL_mouseLocationBottomScrollButton = -2; // mouse is over bottom scroll button
private const int DATAGRIDVIEWRADIOBUTTONCELL_mouseLocationTopScrollButton = -1; // mouse is over top scroll button
private DataGridViewRadioButtonCellLayout layout; // represents the current layout information of the cell
private static int mouseLocationCode = DATAGRIDVIEWRADIOBUTTONCELL_mouseLocationGeneric;
// -3 no particular location
// -2 mouse over bottom scroll button
// -1 mouse over top scroll button
// 0-N mouse over radio button glyph
private PropertyDescriptor displayMemberProperty; // Property descriptor for the DisplayMember property
private PropertyDescriptor valueMemberProperty; // Property descriptor for the ValueMember property
private CurrencyManager dataManager; // Currency manager for the cell's DataSource
private int maxDisplayedItems; // Maximum number of radio buttons displayed by the cell
private int selectedItemIndex; // Index of the currently selected radio button entry
private int focusedItemIndex; // Index of the focused radio button entry
private int pressedItemIndex; // Index of the currently pressed radio button entry
private bool dataSourceInitializedHookedUp; // Indicates whether the DataSource's Initialized event is listened to
private bool valueChanged; // Stores whether the cell's value was changed since it became the current cell
private bool handledKeyDown; // Indicates whether the cell handled the key down notification
private bool mouseUpHooked; // Indicates whether the cell listens to the grid's MouseUp event
/// <summary>
/// DataGridViewRadioButtonCell class constructor.
/// </summary>
public DataGridViewRadioButtonCell()
{
this.maxDisplayedItems = DATAGRIDVIEWRADIOBUTTONCELL_defaultMaxDisplayedItems;
this.layout = new DataGridViewRadioButtonCellLayout();
this.selectedItemIndex = -1;
this.focusedItemIndex = -1;
this.pressedItemIndex = -1;
}
// Implementation of the IDataGridViewEditingCell interface starts here.
/// <summary>
/// Represents the cell's formatted value
/// </summary>
public virtual object EditingCellFormattedValue
{
get
{
return GetEditingCellFormattedValue(DataGridViewDataErrorContexts.Formatting);
}
set
{
if (this.FormattedValueType == null)
{
throw new ArgumentException("FormattedValueType property of a cell cannot be null.");
}
if (value == null || !this.FormattedValueType.IsAssignableFrom(value.GetType()))
{
// Assigned formatted value may not be of the good type, in cases where the app
// is feeding wrong values to the cell in virtual / databound mode.
throw new ArgumentException("The value provided for the DataGridViewRadioButtonCell has the wrong type.");
}
// Try to locate the item that corresponds to the 'value' provided.
for (int itemIndex = 0; itemIndex < this.Items.Count; itemIndex++)
{
object item = this.Items[itemIndex];
object displayValue = GetItemDisplayValue(item);
if (value.Equals(displayValue))
{
// 'value' was found. It becomes the new selected item.
this.selectedItemIndex = itemIndex;
return;
}
}
string strValue = value as string;
if (strValue == string.Empty)
{
// Special case the empty string situation - reset the selected item
this.selectedItemIndex = -1;
return;
}
// 'value' could not be matched against an item in the Items collection.
throw new ArgumentException();
}
}
/// <summary>
/// Keeps track of whether the cell's value has changed or not.
/// </summary>
public virtual bool EditingCellValueChanged
{
get
{
return this.valueChanged;
}
set
{
this.valueChanged = value;
}
}
/// <summary>
/// Returns the current formatted value of the cell
/// </summary>
public virtual object GetEditingCellFormattedValue(DataGridViewDataErrorContexts context)
{
if (this.FormattedValueType == null)
{
throw new InvalidOperationException("FormattedValueType property of a cell cannot be null.");
}
if (this.selectedItemIndex == -1)
{
return null;
}
object item = this.Items[this.selectedItemIndex];
object displayValue = GetItemDisplayValue(item);
// Making sure the returned value has an acceptable type
if (this.FormattedValueType.IsAssignableFrom(displayValue.GetType()))
{
return displayValue;
}
else
{
return null;
}
}
/// <summary>
/// Called by the grid when the cell enters editing mode.
/// </summary>
public virtual void PrepareEditingCellForEdit(bool selectAll)
{
// This cell type has nothing to do here.
}
// Implementation of the IDataGridViewEditingCell interface stops here.
/// <summary>
/// Stores the CurrencyManager associated to the cell's DataSource
/// </summary>
private CurrencyManager DataManager
{
get
{
CurrencyManager cm = this.dataManager;
if (cm == null && this.DataSource != null && this.DataGridView != null &&
this.DataGridView.BindingContext != null && !(this.DataSource == Convert.DBNull))
{
ISupportInitializeNotification dsInit = this.DataSource as ISupportInitializeNotification;
if (dsInit != null && !dsInit.IsInitialized)
{
// The datasource is not ready yet. Attaching to its Initialized event to be notified
// when it's finally ready
if (!this.dataSourceInitializedHookedUp)
{
dsInit.Initialized += new EventHandler(DataSource_Initialized);
this.dataSourceInitializedHookedUp = true;
}
}
else
{
cm = (CurrencyManager)this.DataGridView.BindingContext[this.DataSource];
this.DataManager = cm;
}
}
return cm;
}
set
{
this.dataManager = value;
}
}
/// <summary>
/// Overrides the DataGridViewComboBox's implementation of the DataSource property to
/// initialize the displayMemberProperty and valueMemberProperty members.
/// </summary>
public override object DataSource
{
get
{
return base.DataSource;
}
set
{
if (this.DataSource != value)
{
// Invalidate the currency manager
this.DataManager = null;
ISupportInitializeNotification dsInit = this.DataSource as ISupportInitializeNotification;
if (dsInit != null && this.dataSourceInitializedHookedUp)
{
// If we previously hooked the datasource's ISupportInitializeNotification
// Initialized event, then unhook it now (we don't always hook this event,
// only if we needed to because the datasource was previously uninitialized)
dsInit.Initialized -= new EventHandler(DataSource_Initialized);
this.dataSourceInitializedHookedUp = false;
}
base.DataSource = value;
// Update the displayMemberProperty and valueMemberProperty members.
try
{
InitializeDisplayMemberPropertyDescriptor(this.DisplayMember);
}
catch
{
Debug.Assert(this.DisplayMember != null && this.DisplayMember.Length > 0);
InitializeDisplayMemberPropertyDescriptor(null);
}
try
{
InitializeValueMemberPropertyDescriptor(this.ValueMember);
}
catch
{
Debug.Assert(this.ValueMember != null && this.ValueMember.Length > 0);
InitializeValueMemberPropertyDescriptor(null);
}
if (value == null)
{
InitializeDisplayMemberPropertyDescriptor(null);
InitializeValueMemberPropertyDescriptor(null);
}
}
}
}
/// <summary>
/// Overrides the DataGridViewComboBox's implementation of the DisplayMember property to
/// update the displayMemberProperty member.
/// </summary>
public override string DisplayMember
{
get
{
return base.DisplayMember;
}
set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -