Sep 02
The DataGridView is a powerful grid control included in the .NET Framework. One function missing, however, is the ability to hide the current selection when the DataGridView control is not focused. What the DataGridView class needs is a HideSelection property, similar to the ListView and TextBox. But the .NET designers have not included this capability in the DataGridView class.
Following is a control derived from DataGridView that will automatically hide the current selection when a DataGridView loses focus, and show the selection when the DataGridView regains focus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class DataGridViewEx : DataGridView { private DataGridViewCell m_Cell; protected override void OnGotFocus( EventArgs e ) { if ( this .m_Cell != null ) this .CurrentCell = this .m_Cell; base .OnGotFocus( e ); } protected override void OnLostFocus( EventArgs e ) { this .m_Cell = this .CurrentCell; this .CurrentCell = null ; base .OnLostFocus( e ); } } |
This doesn’t work for an editable DataViewGrid because it gets and loses focus as the editor controls become active. However, if you use OnLeave and OnEnter instead, it works fine.
It works.
But when u do this, u can not edit cells no more..
Try this (it includes some code I tried but that did not work):
private bool hideSelection = true;
[EditorBrowsable(EditorBrowsableState.Always)]
public bool HideSelection
{
get { return hideSelection; }
set { hideSelection = value; }
}
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
if (hideSelection && !this.Focused)
{
DataGridViewElementStates newState = e.State;
if ((newState & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
{
e.PaintBackground(e.ClipBounds, false);
this.Columns[e.ColumnIndex].DefaultCellStyle.SelectionForeColor = e.CellStyle.ForeColor; // could probably be done in hideSelection setter – base OnCellPainting appears to ignore it
e.PaintContent(e.ClipBounds); // problem is, it paints with the selected font, not the foreground font
/* the following does not work, the base OnCellPainting ignors whethe the Selected flag is set.
DataGridViewPaintParts paintParts = DataGridViewPaintParts.ContentForeground;
//paintParts ^= DataGridViewPaintParts.Focus;
newState ^= DataGridViewElementStates.Selected;
newState ^= DataGridViewElementStates.Selected;
DataGridViewCellPaintingEventArgs newE = new DataGridViewCellPaintingEventArgs(
this, // DataGridView dataGridView,
e.Graphics, // Graphics graphics,
e.ClipBounds, // Rectangle clipBounds,
e.CellBounds, // Rectangle cellBounds,
e.RowIndex, // int rowIndex,
e.ColumnIndex, // int columnIndex,
newState, // DataGridViewElementStates cellState,
e.Value, // object value,
e.FormattedValue, // object formattedValue,
e.ErrorText, // string errorText,
e.CellStyle, // DataGridViewCellStyle cellStyle,
e.AdvancedBorderStyle, // DataGridViewAdvancedBorderStyle advancedBorderStyle,
paintParts // DataGridViewPaintParts paintParts
);
base.OnCellPainting(newE);
// This does not work properly either – cannot get a reliable location to start drawing – the arithmetic is more complicated – probably could be done
string text = e.FormattedValue.ToString();
if (!String.IsNullOrWhiteSpace(text))
{
e.Graphics.DrawString(text, e.CellStyle.Font, Brushes.Black, e.CellBounds.X, e.CellBounds.Y);
}
* */
e.Handled = true;
}
}
base.OnCellPainting(e);
}