|
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 !!!
|
|
|
|
|
My software (C# Winform) need to connect to a website to download a file.
The file is sought on the website with the login and password, then given to the client to download.
If I try with the browser, the website gimme a page with the password and the login and a "Connect" button.
I would like to emulate that work, without using the browser.
I'v no problem to connect to the Url and to download, but don't know how to send the login and passwor. I've try the code below, but it doesn't work.
<br />
MyLogin = "Me";<br />
MyPassword = "11111111";<br />
MyUrl = "http://mySite.com/MyPage.php";<br />
clsDownLoadFile MyDownload = new clsDownLoadFile();<br />
clsDownLoadFile.htmlStream MyStream = new clsDownLoadFile.htmlStream();<br />
MyStream = (MyDownload.FindUrl (MyUrl, MyLogin, MyPassword));<br />
if (MyStream != null)<br />
{<br />
if (MyDownload.IsWebConnected())<br />
{<br />
string s = "login="+MyLogin+"+passwd="+MyPassword;<br />
WebClient myWebClient = new WebClient();<br />
Stream postStream = myWebClient.OpenWrite(MyUrl,"POST");<br />
postStream.Write(postArray,0,postArray.Length);<br />
postStream.Close();<br />
try<br />
{<br />
myWebClient.DownloadFile(@"C:\Temp", "MyFile.zip");<br />
}<br />
}<br />
}<br />
I catch an exception when trying to download. I thought beacuse the Identification on the server doen't accept me.
Could someone help me, I drown...
|
|
|
|
|
I have added the combobox to a data grid and populated. When running the app, the column with the combobox is not showing a blank cell. When I click on any cell with the combo box in it, I get the combo box with my data as expected. After I make a change and click on the cell in the next row with the combo box I receive the error below. If I tab off the cell with the combo box into the next row, there is not an error until I tab into the column with the combo box.
combobox.Visible = (cellIsVisible == true) && (readOnly == false);
Additional information: Input string was not in a correct format.
|
|
|
|
|
Example Combobox in datagrid
http://www.doctorcd.8m.com/
seccion manuales
|
|
|
|
|
I'm a little lazy, and I like the visual designer to set up my columns. So I wanted to set up most of the columns, and then make the combo box column, and then move it to the column I wanted. (as opposed to creating the columns in code)
Here is what I did (in VB):
1) create the combo box column (mine is currently something of a bastard between your article and the article by Rami Saad)
<br />
Sub Add_the_ComboBox_to_the_TableStyle()<br />
GridCombo.ctl_Owner = Me.DataGrid1<br />
Dim alComboList As New ArrayList<br />
alComboList.Add(New Q("Blue", "Blue"))<br />
alComboList.Add(New Q("Red", "Red"))<br />
alComboList.Add(New Q("Green", "Green"))<br />
alComboList.Add(New Q("Violet", "Violet"))<br />
GridCombo.ctl_ComboArrayList = alComboList<br />
GridCombo.ctl_DisplayMember = "Display"<br />
GridCombo.ctl_ValueMember = "Value"<br />
GridCombo.HeaderText = "Color"<br />
GridCombo.ReadOnly = False<br />
<br />
<br />
GridCombo.MappingName = "color" ' make sure we don't have one in there mapped to "color"<br />
' this has to correspond to one of the property names of the class that the array is a list of<br />
' since our new grid control is mapped to the color column, it should display<br />
'Me.DataGrid1.TableStyles(0).GridColumnStyles.Add(GridCombo) ' get's added to the last column<br />
End Sub<br />
<br />
2) move the grid combo to another column
<br />
' purpose - the Add function in GridColumnStyles only adds to the last place<br />
' we want our column somewhere else besides last place<br />
Sub GridColumnStyles_MoveLastToWhichColumn(ByVal iCol As Integer)<br />
<br />
Dim iCount As Integer = 0<br />
<br />
Dim tmpStyle As New DataGridTableStyle<br />
Dim cs As DataGridColumnStyle<br />
For Each cs In Me.DataGrid1.TableStyles(0).GridColumnStyles<br />
<br />
If (iCount = iCol) Then<br />
tmpStyle.GridColumnStyles.Add(GridCombo) ' add the grid combo here<br />
End If<br />
tmpStyle.GridColumnStyles.Add(cs)<br />
iCount = iCount + 1<br />
Next<br />
<br />
' at this point, we have a good set of column styles in tmpStyle<br />
Me.DataGrid1.TableStyles(0).GridColumnStyles.Clear()<br />
For Each cs In tmpStyle.GridColumnStyles<br />
Me.DataGrid1.TableStyles(0).GridColumnStyles.Add(cs)<br />
Next<br />
<br />
<br />
End Sub<br />
<br />
3) these are called as follows:
Sub HandleLoad()<br />
Add_the_ComboBox_to_the_TableStyle() ' add our new ComboBox grid style<br />
GridColumnStyles_MoveLastToWhichColumn(2)
|
|
|
|
|
Can i use this with real database?(sql server)
what would i do?
Nelio
|
|
|
|
|
I tried both versions (from the ZIP file and from the thread "combobox display value when not focused"), both have the same problem: if my grid is wide, the combobox control "travels" when I try to scroll the grid horizontally far enough for the corresponding grid column to go off screen. Also, if I reduce the form's width at runtime, the combobox actually gets on top of the grid's vertical scroll bar, if there is one.
Huh?
|
|
|
|
|