|
Hi
Iam having problem with this example.
In the grid there is a combobox in one of the column. When i tab to this column the focus is shifted to the next column instead of this one.
anyone aware of this.
Thanks
Raj
|
|
|
|
|
Do you have any idea why when we pick an item in the combo box in a new row that it always has the first item in the combo box selected?
|
|
|
|
|
I found a work around. The Edit is being called again when we pick the dropdown on a new line. Here are my changes for the work around.
protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) {
if (ReadOnly || DataGridTableStyle.ReadOnly)
return;
// Setup the ComboBox for action.
// This includes positioning the ComboBox and showing it.
// Also select the correct item in the ComboBox before it is shown.
if(!edit){
combobox.Parent = this.DataGridTableStyle.DataGrid;
combobox.Bounds = bounds;
combobox.Size = new Size(this.Width, this.comboBox.Height);
comboBox.SelectedValue = base.GetColumnValueAtRow(source, rowNum);
combobox.Visible = (cellIsVisible == true) && (readOnly == false);
combobox.BringToFront();
combobox.Focus();
}
else{
this.SetColumnValueAtRow(source, rowNum, combobox.SelectedValue);
}
} // Edit
|
|
|
|
|
another problem, when i new a row in the datagrid, the cobombox will show the first element sometimes, but actually the cell of the datagrid have nothing, i mean "null", seems that the text appear in the cobombox do not update to the datagrid.
Dominic Li
|
|
|
|
|
When ever i create an event ie CurrentCellChanged...
Nothing is been displayed in the form..
Please help
Regards,
Vaishali
|
|
|
|
|
Hi,
I want to update the database on the selection change of the combobox.
How can i do it.
Thanks in advance.
Deepak Surana
|
|
|
|
|
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace Test {
#region Form1
//**********************************************************************************************
// Form1
//**********************************************************************************************
public class Form1 : System.Windows.Forms.Form {
private System.Windows.Forms.Button button1;
private Test.DataGrid datagrid;
private DataGridTableStyle tableStyle;
private DataGridTextBoxColumn columnTextBox;
private DataGridComboBoxColumn columnComboBox;
private Button button2;
private System.ComponentModel.Container components = null;
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent() {
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.datagrid = new Test.DataGrid();
this.tableStyle = new Test.DataGridTableStyle();
this.columnTextBox = new System.Windows.Forms.DataGridTextBoxColumn();
this.columnComboBox = new Test.DataGridComboBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.datagrid)).BeginInit();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(214, 214);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(130, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Populate (Designer)";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(350, 214);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(130, 23);
this.button2.TabIndex = 2;
this.button2.Text = "Populate (Code)";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// datagrid
//
this.datagrid.DataMember = "";
this.datagrid.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.datagrid.Location = new System.Drawing.Point(8, 8);
this.datagrid.Name = "datagrid";
this.datagrid.Size = new System.Drawing.Size(472, 200);
this.datagrid.TabIndex = 0;
this.datagrid.TableStyles.AddRange(new System.Windows.Forms.DataGridTableStyle[] {
this.tableStyle});
//
// tableStyle
//
this.tableStyle.ColumnHeadersVisible = false;
this.tableStyle.DataGrid = this.datagrid;
this.tableStyle.GridColumnStyles.AddRange(new System.Windows.Forms.DataGridColumnStyle[] {
this.columnTextBox,
this.columnComboBox});
this.tableStyle.GridLineStyle = System.Windows.Forms.DataGridLineStyle.None;
this.tableStyle.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.tableStyle.MappingName = "TableOne";
this.tableStyle.RowHeaderWidth = 20;
//
// columnTextBox
//
this.columnTextBox.Format = "";
this.columnTextBox.FormatInfo = null;
this.columnTextBox.HeaderText = "Country notes";
this.columnTextBox.MappingName = "notes";
this.columnTextBox.Width = 200;
//
// columnComboBox
//
this.columnComboBox.HeaderText = "Country";
this.columnComboBox.MappingName = "country";
this.columnComboBox.Width = 200;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(492, 245);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.datagrid);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.datagrid)).EndInit();
this.ResumeLayout(false);
}
#endregion
#region Constructor and destructor
public Form1() {
InitializeComponent();
} // Form1
protected override void Dispose(bool disposing) {
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
} // Dispose
[STAThread]
static void Main() {
Application.Run(new Form1());
} // Main
#endregion
private void button1_Click(object sender, System.EventArgs e) {
// Add three MyDataClass objects, to the DataGridComboBox.
// You can see in the source that the MyDataClass doubles as a static array, where the new MyDataClass objects
// automatically is added.
// All the MyDataClass objects can be retreived in an array with the static method: MyDataClass.GetArray().
if (MyDataClass.GetArray().Length == 0) {
new MyDataClass("Denmark");
new MyDataClass("Faroe Islands (DK)");
new MyDataClass("Finland");
new MyDataClass("Greenland (DK)");
new MyDataClass("Iceland");
new MyDataClass("Norway");
new MyDataClass("Sweden");
}
// I don't have a database here, so I make my own DataTable with two columns and finally
// populate it with some test rows.
DataTable table = new DataTable("TableOne");
DataColumn column = table.Columns.Add();
column.ColumnName = "country";
column.DataType = Type.GetType("System.Guid"); // Realy a GUID from the DataGridComboBox.
column = table.Columns.Add();
column.ColumnName = "notes";
column.DataType = Type.GetType("System.String");
table.Rows.Add(new object[] {MyDataClass.GetArray()[0].GUID, "Population 5.368.854"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[1].GUID, "Population 46.011"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[2].GUID, "Population 5.183.545"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[3].GUID, "Population 56.376"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[4].GUID, "Population 279.384"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[5].GUID, "Population 4.525.116"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[6].GUID, "Population 8.876.744"});
// Set the data source to the ComboBox.
columnComboBox.comboBox.DataSource = new ArrayList(MyDataClass.GetArray());
columnComboBox.comboBox.DisplayMember = "name";
columnComboBox.comboBox.ValueMember = "GUID";
columnComboBox.comboBox.Parent = this; // Commit dataset.
// Set the data source to the DataGrid.
datagrid.DataSource = table;
} // button1_Click
private void button2_Click(object sender, System.EventArgs e) {
// Add three MyDataClass objects, to the DataGridComboBox.
// You can see in the source that the MyDataClass doubles as a static array, where the new MyDataClass objects
// automatically is added.
// All the MyDataClass objects can be retreived in an array with the static method: MyDataClass.GetArray().
if (MyDataClass.GetArray().Length == 0) {
new MyDataClass("Denmark");
new MyDataClass("Faroe Islands (DK)");
new MyDataClass("Finland");
new MyDataClass("Greenland (DK)");
new MyDataClass("Iceland");
new MyDataClass("Norway");
new MyDataClass("Sweden");
}
// I don't have a database here, so I make my own DataTable with two columns and finally
// populate it with some test rows.
DataTable table = new DataTable("TableOne");
DataColumn column = table.Columns.Add();
column.ColumnName = "country";
column.DataType = Type.GetType("System.Guid"); // Realy a GUID from the DataGridComboBox.
column = table.Columns.Add();
column.ColumnName = "notes";
column.DataType = Type.GetType("System.String");
table.Rows.Add(new object[] {MyDataClass.GetArray()[0].GUID, "Population 5.368.854"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[1].GUID, "Population 46.011"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[2].GUID, "Population 5.183.545"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[3].GUID, "Population 56.376"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[4].GUID, "Population 279.384"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[5].GUID, "Population 4.525.116"});
table.Rows.Add(new object[] {MyDataClass.GetArray()[6].GUID, "Population 8.876.744"});
// This don't use the DataGridTableStyle, DataGridTextBoxColumn and DataGridComboBoxColumn created
// using the VS designer.
// Create a DataGridTableStyle object.
DataGridTableStyle tableStyle = new DataGridTableStyle();
DataGridTextBoxColumn columnTextBox;
DataGridComboBoxColumn columnComboBox;
tableStyle.RowHeadersVisible = true;
tableStyle.RowHeaderWidth = 20;
// Add customized column: Column "notes", which is a simple text box.
columnTextBox = new DataGridTextBoxColumn();
columnTextBox.MappingName = "notes";
columnTextBox.HeaderText = "Country notes";
columnTextBox.Width = 200;
tableStyle.GridColumnStyles.Add(columnTextBox);
// Add customized column: Column "country", which is the ComboBox.
columnComboBox = new DataGridComboBoxColumn();
columnComboBox.MappingName = "country";
columnComboBox.HeaderText = "Country";
columnComboBox.Width = 200;
tableStyle.GridColumnStyles.Add(columnComboBox);
// Set the data source to the ComboBox.
columnComboBox.comboBox.DataSource = new ArrayList(MyDataClass.GetArray());
columnComboBox.comboBox.DisplayMember = "name";
columnComboBox.comboBox.ValueMember = "GUID";
columnComboBox.comboBox.Parent = this; // Commit dataset.
// Add the custom TableStyle to the DataGrid, and set the data source to the DataGrid.
datagrid.TableStyles.Clear();
datagrid.TableStyles.Add(tableStyle);
datagrid.DataSource = table;
tableStyle.MappingName = "TableOne";
} // button2_Click
} // Form1
#endregion
#region MyDataClass
//**********************************************************************************************
// MyDataClass
//**********************************************************************************************
public class MyDataClass {
private static ArrayList myDataClasses = new ArrayList();
private Guid myGuid;
private string myName;
public MyDataClass(string name) {
myGuid = Guid.NewGuid();
myName = name;
myDataClasses.Add(this);
} // MyDataClass
public Guid GUID {
get {
return myGuid;
}
} // GUID
public string name {
get {
return myName;
}
set {
myName = value;
}
} // name
public static MyDataClass[] GetArray() {
MyDataClass[] objects = new MyDataClass[myDataClasses.Count];
int index = 0;
foreach (MyDataClass item in myDataClasses) {
objects[index] = item;
index++;
}
return objects;
} // GetArray
} // MyDataClass
#endregion
} // Test
|
|
|
|
|
using System;
using System.Drawing;
using System.Collections;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Data;
namespace Test {
#region DataGridComboBoxColumn
//**********************************************************************************************
// DataGridTextBoxColumn
//**********************************************************************************************
public class DataGridComboBoxColumn : DataGridColumnStyle { //DataGridTextBoxColumn {
private DataGridComboBox combobox;
private bool edit;
//-------------------------------------------------------------------------------------------
// Constructors and destructors
//-------------------------------------------------------------------------------------------
public DataGridComboBoxColumn() {
combobox = new DataGridComboBox();
combobox.Visible = false;
combobox.DropDownStyle = ComboBoxStyle.DropDownList;
combobox.Leave += new EventHandler(ComboHide);
combobox.SelectionChangeCommitted += new EventHandler(ComboStartEditing);
edit = false;
} // DataGridComboBoxColumn
//-------------------------------------------------------------------------------------------
// Properties
//-------------------------------------------------------------------------------------------
public ComboBox comboBox {
get {
return combobox;
}
} // comboBox
//-------------------------------------------------------------------------------------------
// ComboBox event handlers
//-------------------------------------------------------------------------------------------
private void ComboHide(object sender, EventArgs e) {
// When the ComboBox looses focus, then simply hide it.
combobox.Hide();
} // ComboHide
private void ComboStartEditing(object sender, EventArgs e) {
// Enter edit mode.
edit = true;
base.ColumnStartedEditing((Control)sender);
} // ComboStartEditing
protected void GridScroll(object sender, EventArgs e) {
combobox.Hide();
} // GridScroll
//-------------------------------------------------------------------------------------------
// Override DataGridColumnStyle
//-------------------------------------------------------------------------------------------
protected override void SetDataGridInColumn(System.Windows.Forms.DataGrid value) {
// Add the ComboBox to the DataGrids controls collection.
// This ensures correct DataGrid scrolling.
value.Controls.Add(combobox);
base.SetDataGridInColumn(value);
value.Scroll +=new EventHandler(GridScroll);
} // SetDataGridInColumn
protected override void Abort(int rowNum) {
// Abort edit mode, discard changes and hide the ComboBox.
edit = false;
Invalidate();
combobox.Hide();
} // Abort
protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) {
if (ReadOnly || DataGridTableStyle.ReadOnly)
return;
// Setup the ComboBox for action.
// This includes positioning the ComboBox and showing it.
// Also select the correct item in the ComboBox before it is shown.
combobox.Parent = this.DataGridTableStyle.DataGrid;
combobox.Bounds = bounds;
combobox.Size = new Size(this.Width, this.comboBox.Height);
comboBox.SelectedValue = base.GetColumnValueAtRow(source, rowNum);//.ToString();
combobox.Visible = (cellIsVisible == true) && (readOnly == false);
combobox.BringToFront();
combobox.Focus();
} // Edit
protected override bool Commit(System.Windows.Forms.CurrencyManager source, int rowNum) {
// Commit the selected value from the ComboBox to the DataGrid.
if (edit == true) {
edit = false;
this.SetColumnValueAtRow(source, rowNum, combobox.SelectedValue);
}
return true;
} // Commit
protected override object GetColumnValueAtRow(System.Windows.Forms.CurrencyManager source, int rowNum) {
// Return the display text associated with the data, insted of the
// data from the DataGrid datasource.
return combobox.GetDisplayText(base.GetColumnValueAtRow(source, rowNum));
} // GetColumnValueAtRow
protected override void SetColumnValueAtRow(CurrencyManager source, int rowNum, object value) {
// Save the data (value) to the DataGrid datasource.
// æøå
try {
base.SetColumnValueAtRow(source, rowNum, value);
} catch {}
} // SetColumnValueAtRow
protected override int GetMinimumHeight() {
// Return the ComboBox preferred height, plus a few pixels.
return combobox.PreferredHeight + 2;
} // GetMinimumHeight
protected override int GetPreferredHeight(Graphics g, object val) {
// Return the font height, plus a few pixels.
return FontHeight + 2;
} // GetPreferredHeight
protected override Size GetPreferredSize(Graphics g, object val) {
// Return the preferred width.
// Iterate through all display texts in the dropdown, and measure each
// text width.
int widest = 0;
SizeF stringSize = new SizeF(0, 0);
foreach (string text in combobox.GetDisplayText()) {
stringSize = g.MeasureString(text, base.DataGridTableStyle.DataGrid.Font);
if (stringSize.Width > widest) {
widest = (int)Math.Ceiling(stringSize.Width);
}
}
return new Size(widest + 25, combobox.PreferredHeight + 2);
} // GetPreferredSize
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) {
Paint(g, bounds, source, rowNum, false);
} // Paint
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) {
string text = GetColumnValueAtRow(source, rowNum).ToString();
Brush backBrush = new SolidBrush(base.DataGridTableStyle.BackColor);
Brush foreBrush = new SolidBrush(base.DataGridTableStyle.ForeColor);
Rectangle rect = bounds;
StringFormat format = new StringFormat();
// Handle that the row can be selected.
if (base.DataGridTableStyle.DataGrid.IsSelected(rowNum) == true) {
backBrush = new SolidBrush(base.DataGridTableStyle.SelectionBackColor);
foreBrush = new SolidBrush(base.DataGridTableStyle.SelectionForeColor);
}
// Handle align to right.
if (alignToRight == true) {
format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
}
// Handle alignment.
switch (this.Alignment) {
case HorizontalAlignment.Left:
format.Alignment = StringAlignment.Near;
break;
case HorizontalAlignment.Right:
format.Alignment = StringAlignment.Far;
break;
case HorizontalAlignment.Center:
format.Alignment = StringAlignment.Center;
break;
}
// Paint.
format.FormatFlags = StringFormatFlags.NoWrap;
g.FillRectangle(backBrush, rect);
rect.Offset(0, 2);
rect.Height -= 2;
g.DrawString(text, this.DataGridTableStyle.DataGrid.Font, foreBrush, rect, format);
format.Dispose();
} // PaintText
} // DataGridComboBoxColumn
#endregion
#region DataGridComboBox
//**********************************************************************************************
// DataGridComboBox
//**********************************************************************************************
public class DataGridComboBox : ComboBox {
private const int WM_KEYUP = 0x101;
protected override void WndProc(ref System.Windows.Forms.Message message) {
// Ignore keyup to avoid problem with tabbing and dropdown list.
if (message.Msg == WM_KEYUP) {
return;
}
base.WndProc(ref message);
} // WndProc
public string GetValueText(int index) {
// Validate the index.
if ((index < 0) && (index >= base.Items.Count))
throw new IndexOutOfRangeException("Invalid index.");
// Get the text.
string text = string.Empty;
int memIndex = -1;
try {
base.BeginUpdate();
memIndex = base.SelectedIndex;
base.SelectedIndex = index;
text = base.SelectedValue.ToString();
base.SelectedIndex = memIndex;
} catch {
} finally {
base.EndUpdate();
}
return text;
} // GetValueText
public string GetDisplayText(int index) {
// Validate the index.
if ((index < 0) && (index >= base.Items.Count))
throw new IndexOutOfRangeException("Invalid index.");
// Get the text.
string text = string.Empty;
int memIndex = -1;
try {
base.BeginUpdate();
memIndex = base.SelectedIndex;
base.SelectedIndex = index;
text = base.SelectedItem.GetType().GetProperty(base.DisplayMember).GetValue(base.SelectedItem, new object[0]).ToString();
base.SelectedIndex = memIndex;
} catch {
} finally {
base.EndUpdate();
}
return text;
} // GetDisplayText
public string GetDisplayText(object value) {
// Get the text.
string text = string.Empty;
int memIndex = -1;
try {
base.BeginUpdate();
memIndex = base.SelectedIndex;
base.SelectedValue = value;//.ToString();
text = base.SelectedItem.GetType().GetProperty(base.DisplayMember).GetValue(base.SelectedItem, new object[0]).ToString();
} catch {
// If the value is invalid, return the first items display text.
return GetDisplayText(0);
} finally {
base.SelectedIndex = memIndex;
base.EndUpdate();
}
return text;
} // GetDisplayText
public string[] GetDisplayText() {
// Get the text.
string[] text = new string[base.Items.Count];
int memIndex = -1;
try {
base.BeginUpdate();
memIndex = base.SelectedIndex;
for (int index = 0; index < base.Items.Count; index++) {
base.SelectedIndex = index;
text[index] = base.SelectedItem.GetType().GetProperty(base.DisplayMember).GetValue(base.SelectedItem, new object[0]).ToString();
}
} catch {
} finally {
base.SelectedIndex = memIndex;
base.EndUpdate();
}
return text;
} // GetDisplayText
} // DataGridComboBox
#endregion
#region DataGridEventColumn
//**********************************************************************************************
// DataGridEventColumn
//**********************************************************************************************
public delegate string DataGridEventColumnEvent(CurrencyManager rowSource, int rowNum, object rowData);
public class DataGridEventColumn : DataGridColumnStyle {
private event DataGridEventColumnEvent eGetText = null;
//-------------------------------------------------------------------------------------------
// Constructors and destructors
//-------------------------------------------------------------------------------------------
public DataGridEventColumn() {
} // DataGridEventColumn
//-------------------------------------------------------------------------------------------
// events
//-------------------------------------------------------------------------------------------
public event DataGridEventColumnEvent EventGetText {
add {
eGetText += value;
}
remove {
eGetText -= value;
}
} // EventGetText
private string OnGetText(CurrencyManager rowSource, int rowNum, object rowData) {
try {
return eGetText(rowSource, rowNum, rowData);
} catch {
return string.Empty;
}
} // OnGetText
//-------------------------------------------------------------------------------------------
// Override DataGridColumnStyle
//-------------------------------------------------------------------------------------------
protected override void Abort(int rowNum) {
} // Abort
protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) {
} // Edit
protected override bool Commit(System.Windows.Forms.CurrencyManager source, int rowNum) {
return true;
} // Commit
protected override int GetMinimumHeight() {
// Return the ComboBox preferred height, plus a few pixels.
return 2;
} // GetMinimumHeight
protected override int GetPreferredHeight(Graphics g, object val) {
// Return the font height, plus a few pixels.
return FontHeight + 2;
} // GetPreferredHeight
protected override Size GetPreferredSize(Graphics g, object val) {
return new Size(50, FontHeight + 2);
} // GetPreferredSize
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) {
Paint(g, bounds, source, rowNum, false);
} // Paint
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) {
string text = OnGetText(source, rowNum, GetColumnValueAtRow(source, rowNum));
Brush backBrush = new SolidBrush(base.DataGridTableStyle.BackColor);
Brush foreBrush = new SolidBrush(base.DataGridTableStyle.ForeColor);
Rectangle rect = bounds;
StringFormat format = new StringFormat();
// Handle that the row can be selected.
if (base.DataGridTableStyle.DataGrid.IsSelected(rowNum) == true) {
backBrush = new SolidBrush(base.DataGridTableStyle.SelectionBackColor);
foreBrush = new SolidBrush(base.DataGridTableStyle.SelectionForeColor);
}
// Handle align to right.
if (alignToRight == true) {
format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
}
// Handle alignment.
switch (this.Alignment) {
case HorizontalAlignment.Left:
format.Alignment = StringAlignment.Near;
break;
case HorizontalAlignment.Right:
format.Alignment = StringAlignment.Far;
break;
case HorizontalAlignment.Center:
format.Alignment = StringAlignment.Center;
break;
}
// Paint.
format.FormatFlags = StringFormatFlags.NoWrap;
g.FillRectangle(backBrush, rect);
rect.Offset(0, 2);
rect.Height -= 2;
g.DrawString(text, this.DataGridTableStyle.DataGrid.Font, foreBrush, rect, format);
format.Dispose();
} // PaintText
} // DataGridEventColumn
#endregion
#region BindingList
//**********************************************************************************************
// BindingList
//**********************************************************************************************
public class BindingList : IBindingList, IComparer {
private DataGrid datagrid = null;
private event ListChangedEventHandler eListChanged = null;
private ArrayList list = new ArrayList();
private PropertyDescriptor sortProperty = null;
private ListSortDirection sortDirection = ListSortDirection.Ascending;
private ICloneable addNewClone = null;
private Hashtable comparers = new Hashtable();
public BindingList(DataGrid datagrid, ICloneable addNewClone) {
this.datagrid = datagrid;
this.addNewClone = addNewClone;
} // BindingList
public BindingList(DataGrid datagrid, ICloneable addNewClone, ICollection collection) {
this.datagrid = datagrid;
this.addNewClone = addNewClone;
list.AddRange(collection);
} // BindingList
public void SetComparer(IComparer comparer, string propertyName) {
// Remove the comparer registed with the argumented property name.
if (comparers.ContainsKey(propertyName) == true) {
comparers.Remove(propertyName);
}
// Register the argumented comparer with the argumented property name.
if (comparer != null) {
comparers.Add(propertyName, comparer);
}
} // SetComparer
#region IBindingList Members
public event ListChangedEventHandler ListChanged {
add {
eListChanged += value;
}
remove {
eListChanged -= value;
}
} // ListChanged
private void OnListChanged(ListChangedEventArgs e) {
try {
if (eListChanged != null)
eListChanged(this, e);
} catch {}
} // OnListChanged
public void AddIndex(PropertyDescriptor property) {
// The list must support this method. However, support for this method can be a nonoperation.
sortProperty = property;
sortDirection = ListSortDirection.Ascending;
} // AddIndex
public void RemoveIndex(PropertyDescriptor property) {
// The list must support this method. However, support for this method can be a nonoperation.
sortProperty = null;
sortDirection = ListSortDirection.Ascending;
} // RemoveIndex
public bool AllowNew {
get {
return true;
}
} // AllowNew
public bool AllowEdit {
get {
return true;
}
} // AllowEdit
public bool AllowRemove {
get {
return true;
}
} // AllowRemove
public bool SupportsSorting {
get {
return true;
}
} // SupportsSorting
public bool SupportsSearching {
get {
return true;
}
} // SupportsSearching
public bool SupportsChangeNotification {
get {
return true;
}
} // SupportsChangeNotification
public bool IsSorted {
get {
return sortProperty != null;
}
} // IsSorted
public PropertyDescriptor SortProperty {
get {
return sortProperty;
}
} // SortProperty
public System.ComponentModel.ListSortDirection SortDirection {
get {
return sortDirection;
}
} // SortDirection
public void ApplySort(PropertyDescriptor property, System.ComponentModel.ListSortDirection direction) {
sortProperty = property;
sortDirection = direction;
list.Sort(this);
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
} // ApplySort
public void RemoveSort() {
sortProperty = null;
sortDirection = ListSortDirection.Ascending;
// Sort on the objects CompareTo.
// list.Sort();
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
} // RemoveSort
public int Find(PropertyDescriptor property, object key) {
// This method will select the first row where the value of the property parameter equals the value of the
// key parameter.
foreach(object obj in list) {
if (Compare(obj, key) == 0) {
return list.IndexOf(obj);
}
}
return -1;
} // Find
public object AddNew() {
// The new object is added as the last row, which mens that the list isn't sorted anymore.
sortProperty = null;
sortDirection = ListSortDirection.Ascending;
// Clone the object and add it.
object addNewObject = addNewClone.Clone();
int addNewIndex = list.Add(addNewObject);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, addNewIndex));
// Normally the user can regret the addition of a new row, by pressing the ESC button twice - but this
// only works if the data objects in the list collection implements the IEditableObject interface.
//
// I don't like the idea that the objects used should implement some interface and perform some actions
// which should be handled by the DataGrid class itself!
//
// One option is to implement and use a proxy class like BindingListRow and implement the IEditableObject
// interface in there.
//
// An other option which is a trade-off, because it disables the feature where the user can regret the
// addition of a new row, is the following few lines of code.
if ((addNewObject is IEditableObject) == false) {
// Remember which cell is active and have the focus.
DataGridCell activeCell = datagrid.CurrentCell;
// ??? IT DOES THE TRICK ???. This might change the active cell.
OnListChanged(new ListChangedEventArgs(ListChangedType.PropertyDescriptorChanged, -1));
// Refocus the correct cell.
datagrid.CurrentCell = activeCell;
}
// Return the added object.
return addNewObject;
} // AddNew
#endregion
#region IList Members
public bool IsReadOnly {
get {
return list.IsReadOnly;
}
} // IsReadOnly
public bool IsFixedSize {
get {
return list.IsFixedSize;
}
} // IsFixedSize
public void Clear() {
list.Clear();
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
} // Clear
public bool Contains(object value) {
return list.Contains(value);
} // Contains
public int IndexOf(object value) {
return list.IndexOf(value);
} // IndexOf
public object this[int index] {
get {
return list[index];
}
set {
list[index] = value;
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index));
}
} // this
public int Add(object value) {
int index = list.Add(value);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index));
return index;
} // Add
public void AddRange(ICollection c) {
list.AddRange(c);
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
} // AddRange
public void Insert(int index, object value) {
list.Insert(index, value);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index));
} // Insert
public void Remove(object value) {
int index = list.IndexOf(value);
if (index > -1) {
list.Remove(value);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
}
} // Remove
public void RemoveAt(int index) {
list.RemoveAt(index);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
} // RemoveAt
#endregion
#region ICollection Members
public bool IsSynchronized {
get {
return list.IsSynchronized;
}
} // IsSynchronized
public int Count {
get {
return list.Count;
}
} // Count
public void CopyTo(Array array, int index) {
list.CopyTo(array, index);
} // CopyTo
public object SyncRoot {
get {
return list.SyncRoot;
}
} // SyncRoot
#endregion
#region IEnumerable Members
public IEnumerator GetEnumerator() {
return list.GetEnumerator();
} // GetEnumerator
#endregion
#region IComparer Members
public int Compare(object x, object y) {
int result = 0;
IComparer comparer;
IComparable comparable;
object propertyX;
object propertyY;
// Get the actual objects that we are comparing.
// These are basically fields from the X and Y objects.
propertyX = sortProperty.GetValue(x);
propertyY = sortProperty.GetValue(y);
// Deal with one or both being null.
if ((propertyX == null) && (propertyY == null)) {
result = 0;
} else if (propertyX == null) {
result = -1;
} else if (propertyY == null) {
result = 1;
} else {
if (comparers.ContainsKey(sortProperty.Name) == true) {
// Compare using the registed comparer.
comparer = (IComparer)comparers[sortProperty.Name];
result = comparer.Compare(propertyX, propertyY);
} else {
// Get the IComparable interface.
if (propertyX is IComparable) {
comparable = (IComparable)propertyX;
result = comparable.CompareTo(propertyY);
} else {
// Do normal comparison.
string.Compare(propertyX.ToString(), propertyY.ToString());
}
}
}
// If the direction is descending, reverse the sign.
if (sortDirection == ListSortDirection.Descending) {
result = -result;
}
return result;
} // Compare
#endregion
} // BindingList
#endregion
#region DataGridTableStyle
//**********************************************************************************************
// DataGridTableStyle.
//
// Get the datagrid combobox working with the VS designer.
// Code posted by Thosmos.
// http://www.microsoft.com/belux/nl/msdn/community/columns/jtielens/datagrid.mspx
//**********************************************************************************************
public class DataGridTableStyle : System.Windows.Forms.DataGridTableStyle {
[Editor(typeof(DataGridColumnStylesCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
public override System.Windows.Forms.GridColumnStylesCollection GridColumnStyles {
get {
return base.GridColumnStyles;
}
} // GridColumnStyles
private class DataGridColumnStylesCollectionEditor : System.ComponentModel.Design.CollectionEditor {
public DataGridColumnStylesCollectionEditor(Type type): base(type) {
} // DataGridColumnStylesCollectionEditor
protected override Type[] CreateNewItemTypes() {
return new Type[] {
typeof(DataGridTextBoxColumn),
typeof(DataGridBoolColumn),
typeof(DataGridComboBoxColumn)
};
} // CreateNewItemTypes
} // DataGridColumnStylesCollectionEditor
} // DataGridTableStyle
public class DataGrid : System.Windows.Forms.DataGrid {
[Editor(typeof(TableStylesCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
public new System.Windows.Forms.GridTableStylesCollection TableStyles {
get {
return base.TableStyles;
}
} // GridTableStylesCollection
private class TableStylesCollectionEditor : System.ComponentModel.Design.CollectionEditor {
public TableStylesCollectionEditor(Type type): base(type) {
} // TableStylesCollectionEditor
protected override Type[] CreateNewItemTypes() {
return new Type[] {typeof(DataGridTableStyle)};
} // CreateNewItemTypes
} // TableStylesCollectionEditor
} // DataGrid
#endregion
} // Test
|
|
|
|
|
this DataGridComboBox is Working fine after the fixes to the GetDisplayText method.
public string GetDisplayText(object value)
{
// Get the text.
string text = string.Empty;
int memIndex = -1;
try
{
base.BeginUpdate();
memIndex = base.SelectedIndex;
base.SelectedValue = value.ToString();
// fix suggested by someone.
text = base.SelectedItem.GetType().GetProperty(base.DisplayMember).GetValue(base.SelectedItem, new object[0]).ToString();
base.SelectedIndex = memIndex;
}
catch
{
// Added this to fix the New Row problem.
return GetValueText(0);
}
finally
{
base.EndUpdate();
}
return text;
} // GetDisplayText
|
|
|
|
|
Also add this code ( solution given by someone in one of the threads)
protected void GridScroll(object sender, EventArgs e)
{
combobox.Hide();
}
protected override void SetDataGridInColumn(DataGrid value)
{
value.Controls.Add(combobox);
base.SetDataGridInColumn(value);
value.Scroll +=new EventHandler(GridScroll);
}
for the grid scrolling problem...
|
|
|
|
|
|
The above datagrid combobox is a shareware .. and it expires after few days..
|
|
|
|
|
Hi All
I have created my own control called FtInchControl which has a textbox in it and changes the text value based on some logic.
I have created a Column Style called DataGridFtInchColumn which is on similar lines to DataGridComboBoxColumn.
The column in the dataGrid is not Editable ..?? how should i make it editable??
please reply
sandeep
|
|
|
|
|
I made a different combo box grid after looking around at several others, including this one. Mine has the ability to add new items to the combobox dynamically. In one of my examples I added an item in the ComboBox choices that says "<add new="">". When someone selects that choice, I am adding a new item to the list of choices, and automatically selecting that new item.
My intention was to pop up a dialog when someone selects "<add new="">" and then take their data from the dialog box to stuff into the list of valid choices. This part is simple to do once you see how to add a new item.
You want to do something a little different - I guess you want to allow them to edit an existing choice right there in the grid. My code may help you but it's not exactly what you want.
http://www.ericengler.com/downloads/DataGridComboBoxDemo.zip
|
|
|
|
|
I want Data Picker in Datagrid?????
|
|
|
|
|
Hi
I wounder if you could send me the DataGridComboBoxColumn.cs in VB.Net instead.
I would be greatfull
I have tried to convert the code on a page, but with no luck.
Fia
|
|
|
|
|
Se puede hacer que una columna se tengan diferentes controles.
Por Ejemplo:
datagridview1[0,0] ==> en esa columna agregar un datagridviewTexboxCell
datagridview1[0,1] ==> en esa columna agregar un datagridviewComboBoxCell
donde: [columna,fila]
|
|
|
|
|
I used your code to my project.when I use below code, When I execute the project it gives
An unhandled exception of type 'System.NullReferenceException' occurred in SPOT.exe
Additional information: Object reference not set to an instance of an object(I bold that the place error occured)
if(Data.Tables["Atom"].Columns[i].ColumnName.Equals("Types"))
{
comboboxColStyle = new DataGridComboBoxColumn();
//MessageBox.Show(Data.Tables.IndexOf("Type").ToString());
comboboxColStyle.ComboBox.DataSource = Data.Tables["Type"];b>//In here I had problem
comboboxColStyle.ComboBox.DisplayMember = Data.Tables["Type"].Columns["Name"].ColumnName;;
//comboboxColStyle.ComboBox.ValueMember=Data.Tables["Type"].Columns["Name"].ColumnName;
comboboxColStyle.HeaderText = "Types";
comboboxColStyle.MappingName = Data.Tables["Atom"].Columns[i].ColumnName;
tableStyle.GridColumnStyles.Add(comboboxColStyle);
}
else
{
// add standard textbox columns for the other columns
textboxColStyle = new DataGridTextBoxColumn();
textboxColStyle.HeaderText = Data.Tables["Atom"].Columns[i].ColumnName;
textboxColStyle.MappingName = Data.Tables["Atom"].Columns[i].ColumnName;
textboxColStyle.Width=250;
tableStyle.GridColumnStyles.Add(textboxColStyle);
}
dbn_01
|
|
|
|
|
I think the DataSource of this combo box can only be an arraylist populated with objects which have the properties which are set to the DisplayMember,ValueMember of the combobox !!
|
|
|
|
|
I want to get the selected value of comboBox in dataGrid and also which event should i handle to reflect changes on change value in comboBox.
Regards,
Munazzah Nawaz
|
|
|
|
|
hi how Can I To Get the Value from tis comobox in the datagrid.
it's like this? " mydatagrid(1,2).selesctedValue" ??/
|
|
|
|
|
I have implemented your solution and it almost works for me. The only issue that i have is if I am working on a newly created line and I choose the first item in the drop down it doesn't retain my value. If I choose the second item it works fine. If I add the row with the second Item and go back to the field and then change it to the first item then it works fine.
|
|
|
|
|
You're right, but the problem is bigger than just a new row issue. If you add this to the catch clause of GetDisplayText is becomes more apparent, but I haven't solved it yet:
catch
{
return "oops";
}
I tried the authors original code and his modified code (using GetProperty), and the problem exists either way.
|
|
|
|
|
just put
return GetValueText(0);
in the catch ... It works !!!
|
|
|
|
|
this also doesnt work !!!
|
|
|
|
|