ComboBox in DataGrid,

P

pei_world

I want to implement a key hit with enter to dropdown a combobox that is in
the datagrid. in this case I need to override its original behaviours. I
found some codes from the web. Does anyone know how to use this code? please
help!



http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_20862953.html




using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
using System.Collections;
using System.Diagnostics;
using System.Reflection;

namespace AdvancedDataGrid
{
/// <summary>
/// Implementation of a ComboBox as a column in a DataGrid
/// </summary>
public class DataGridDataBoundComboBoxColumn : DataGridTextBoxColumn
{
private ComboBox internalComboBox = new ComboBox();
private bool currentlyInEdit = false;
private CurrencyManager source = null;
private int rowNum = -1;
private AdvancedDataGrid.MyDataGrid dataGrid = null;

#region Properties
private object nullValue = DBNull.Value;
/// <summary>
/// Gives a value that will be considered null and will be replaced for
showing by NullValue
/// </summary>
public object NullValue
{
set {this.nullValue = value;}
get {return this.nullValue;}
}

private object nullCorrespondingValue = null;
/// <summary>
/// Gives a value that will replace the null values (given by NullValue)
for showing
/// </summary>
public object NullCorrespondingValue
{
set {this.nullCorrespondingValue = value;}
get {return this.nullCorrespondingValue;}
}

public object DataSource
{
set
{
// If the display member or value member is wrong,
// this line will clear it
this.internalComboBox.DataSource = value;
SetComboBoxDropDownWidth();
}
get { return this.internalComboBox.DataSource; }
}
public string DisplayMember
{
set
{
this.internalComboBox.DisplayMember = value;
SetComboBoxDropDownWidth();
}
get { return this.internalComboBox.DisplayMember; }
}
public string ValueMember
{
set {this.internalComboBox.ValueMember = value; }
get { return this.internalComboBox.ValueMember; }
}
#endregion

#region Construction
public DataGridDataBoundComboBoxColumn () : base()
{
this.internalComboBox.Visible = false;
this.internalComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
// Some events that guarantee correct working
this.internalComboBox.LostFocus += new EventHandler
(OnInternalComboBoxLostFocus);
}
#endregion

#region Event handlers for the combo box
private void OnInternalComboBoxLostFocus (object sender, EventArgs e)
{
if ((sender is DataGrid && !this.internalComboBox.Focused) ||
sender == this.internalComboBox)
{
if (this.currentlyInEdit)
Commit (this.source, this.rowNum);
}
}
#endregion

#region Key management
/// <summary>
/// Handles opening and closing of the ComboBox with the keyboard
/// For this function to work, the data grid should be of type
AdvancedDataGrid
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
public bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!this.currentlyInEdit)
return false;

if (keyData == Keys.Down)
{
// Try to select next or the first item
if (this.internalComboBox.SelectedIndex <
this.internalComboBox.Items.Count - 1)
this.internalComboBox.SelectedIndex++;
else if (this.internalComboBox.Items.Count > 0)
this.internalComboBox.SelectedIndex = 0;
return true;
}
else if (keyData == Keys.Up)
{
// Try to select previous or the last item
if (this.internalComboBox.SelectedIndex > 0)
this.internalComboBox.SelectedIndex--;
else if (this.internalComboBox.Items.Count > 0)
this.internalComboBox.SelectedIndex =
this.internalComboBox.Items.Count - 1;
return true;
}
else if ((keyData == (Keys.Up | Keys.Alt) ||
keyData == (Keys.Down | Keys.Alt)) &&
!this.internalComboBox.DroppedDown)
{
this.internalComboBox.DroppedDown = true;
return true;
}
// Keys.Down | Keys.Alt work automatically if DropedDown
else if ((keyData == Keys.Enter || keyData == (Keys.Up | Keys.Alt)) &&
this.internalComboBox.DroppedDown)
{
HideDropDown();
return true;
}
else if (keyData == Keys.Escape)
{
Abort (this.rowNum);
return true;
}

return false;
}
#endregion

#region Overriden methods

protected override object GetColumnValueAtRow (CurrencyManager source, int
rowNum)
{
object val = base.GetColumnValueAtRow (source, rowNum);
// Check for the null value
if (Object.Equals (val, this.NullValue) && this.NullCorrespondingValue !=
null)
val = this.NullCorrespondingValue;

foreach (object o in this.internalComboBox.Items)
{
object oVal = GetValueMember (o);
if ((oVal == null && val == null) ||
(oVal != null && oVal.Equals (val)))
return GetDisplayMember (o);
}
return DBNull.Value;
}

protected override void Abort(int rowNum)
{
// If in read only mode, just follow the basic methods
if (this.DataGridTableStyle.DataGrid.ReadOnly || this.ReadOnly ||
(this.DataGridTableStyle.DataGrid.DataSource is DataView &&
!((DataView)this.DataGridTableStyle.DataGrid.DataSource).AllowEdit))
{
base.Abort (rowNum);
return;
}

if(this.currentlyInEdit)
{
this.currentlyInEdit = false;
this.source = null;
this.rowNum = -1;
this.internalComboBox.Hide();
if (this.internalComboBox.DroppedDown)
HideDropDown();
}
}

protected override bool Commit(CurrencyManager dataSource,int rowNum)
{
// If in read only mode, just follow the basic methods
if (this.DataGridTableStyle.DataGrid.ReadOnly || this.ReadOnly ||
(this.DataGridTableStyle.DataGrid.DataSource is DataView &&
!((DataView)this.DataGridTableStyle.DataGrid.DataSource).AllowEdit))
return base.Commit(dataSource, rowNum);

if(this.currentlyInEdit)
{
object selValue = this.internalComboBox.SelectedValue;
if (selValue == null || Object.Equals (selValue,
this.NullCorrespondingValue))
selValue = this.NullValue;
SetColumnValueAtRow(dataSource, rowNum, selValue);

this.currentlyInEdit = false;
this.source = null;
this.rowNum = -1;
this.internalComboBox.Hide();
if (this.internalComboBox.DroppedDown)
HideDropDown();
}

return true;
}

protected override void Edit(CurrencyManager source, int rowNum, Rectangle
bounds, bool readOnly, string instantText, bool cellIsVisible)
{
// If in read only mode, just follow the basic methods
if (this.DataGridTableStyle.DataGrid.ReadOnly || this.ReadOnly ||
(this.DataGridTableStyle.DataGrid.DataSource is DataView &&
!((DataView)this.DataGridTableStyle.DataGrid.DataSource).AllowEdit))
{
base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
return;
}

if (this.currentlyInEdit)
return;

if(!cellIsVisible)
return;

// Important: show it before setting the selected value
// otherwise in some cases the value from the previous edit is returned
// (when the drop down is open with the mouse, a new value is pointed
// and Tab is pressed)
this.internalComboBox.Bounds = bounds;
this.internalComboBox.Show();

// Get the underlying value
// The current implementation of GetColumnValueAtRow will return the
DisplayMember
object val = base.GetColumnValueAtRow (source, rowNum);
// Check for the null value
if (Object.Equals (val, this.NullValue) && this.NullCorrespondingValue !=
null)
val = this.NullCorrespondingValue;

if (val == null || val == DBNull.Value)
if (this.internalComboBox.Items.Count > 0)
this.internalComboBox.SelectedIndex = 0;
else
this.internalComboBox.SelectedIndex = -1;
else
this.internalComboBox.SelectedValue = val;

this.currentlyInEdit = true;
this.source = source;
this.rowNum = rowNum;

ColumnStartedEditing (this.internalComboBox);
}

protected override int GetMinimumHeight()
{
return this.internalComboBox.PreferredHeight + 1;
}

protected override void SetDataGridInColumn(DataGrid value)
{
base.SetDataGridInColumn (value);

if (value == this.dataGrid)
return;

Debug.Assert (value != null);
Debug.Assert (value is AdvancedDataGrid.MyDataGrid,"The used data grid
should be of type AdvancedDataGrid");

if (this.dataGrid != null)
{
this.dataGrid.Controls.Remove (this.internalComboBox);
this.dataGrid.LostFocus -= new EventHandler
(OnInternalComboBoxLostFocus);
}

this.dataGrid = (AdvancedDataGrid.MyDataGrid)value;

this.dataGrid.Controls.Add(this.internalComboBox);
// Some events that guarantee correct working
this.dataGrid.LostFocus += new EventHandler
(OnInternalComboBoxLostFocus);
}
#endregion

#region Helper functions
private void HideDropDown()
{
// Unknown why, the value is lost when DroppedDown is set to false
object val = this.internalComboBox.SelectedValue;
this.internalComboBox.DroppedDown = false;
this.internalComboBox.SelectedValue = val;
}
private object GetMember (object o, string member)
{
DataRow row = null;
if (o is DataRowView)
row = ((DataRowView)o).Row;
if (o is DataRow)
row = (DataRow)o;
if (row != null)
{
object ret = row[member];
if (ret == null)
return DBNull.Value;
else
return ret;
}
else
{
PropertyInfo pi = o.GetType().GetProperty (member);
Debug.Assert (pi != null);
return pi.GetValue (o, null);
}
}

private string GetDisplayMember (object o)
{
if (o == null || o == DBNull.Value)
return this.NullText;
object val = GetMember (o, this.internalComboBox.DisplayMember);
if (val == null || val == DBNull.Value)
return this.NullText;
else
return val.ToString();
}

private object GetValueMember (object o)
{
return GetMember (o, this.internalComboBox.ValueMember);
}

/// <summary>
/// Sets the DropDownWidth property of the combo box if all needed
/// properties are already set
/// </summary>
private void SetComboBoxDropDownWidth()
{
if (this.internalComboBox.DataSource == null ||
this.internalComboBox.DisplayMember == null ||
this.internalComboBox.DisplayMember == String.Empty)
return;

Graphics g = this.internalComboBox.CreateGraphics ();
float w = 0;
foreach (object o in this.internalComboBox.Items)
w = Math.Max (w, g.MeasureString (GetDisplayMember (o),
this.internalComboBox.Font).Width);
if (w > 0)
this.internalComboBox.DropDownWidth = (int)(w + 0.5);
}
#endregion
}
}
 
P

Pete Davis

What exactly is your question? Do you want to know how to integrate this
code into your own application so that you can have a combo box in a grid or
does your question have to do with using the enter key to activate the
dropdown? Or is your question as you ask it: Do you want to know if we know
how to use that code? I doubt that's really your question.

If you can be more specific about your question, you're more likely to get a
response.

Pete


pei_world said:
I want to implement a key hit with enter to dropdown a combobox that is in
the datagrid. in this case I need to override its original behaviours. I
found some codes from the web. Does anyone know how to use this code? please
help!
[snip]
 
P

pei_world

sorry about my question, I have integrated a combobox into the datagrid. But
when I try to use keyboard to control the datagrid, after I press the Enter
key, combobox dropped down, however, when I try to select the next item on
the combobox, it move to the next row of the datagrid. how can I use this
code to override its default action.
what I try to do are:
1.press Enter key to show Combobox Dropdown list
2.Press UP or Down key to select item
3.Press Enter key to hide Dropdown list

Also, How to use this code in my application? I am using other code to
integrate combobox into datagrid.


Pete Davis said:
What exactly is your question? Do you want to know how to integrate this
code into your own application so that you can have a combo box in a grid
or
does your question have to do with using the enter key to activate the
dropdown? Or is your question as you ask it: Do you want to know if we
know
how to use that code? I doubt that's really your question.

If you can be more specific about your question, you're more likely to get
a
response.

Pete


pei_world said:
I want to implement a key hit with enter to dropdown a combobox that is
in
the datagrid. in this case I need to override its original behaviours. I
found some codes from the web. Does anyone know how to use this code? please
help!
[snip]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top