DataGrid containing multiple DataGridColumnStyle for one Column

V

vijai thoppae

Hello,

I've a strange requirement using DataGrid. I've defined 2 columns out of
which upfront i know first column's ColumStyle which is a ComboBox . The
second column's ColumnStyle needs to be different based upon first column
selection. It can be either a simple Textbox column or ComboBox or Command
btn. The user will be able to add any number of rows at run time. Based upon
Firstcolumn val, the second column shd display accordingly . Is it possible
to achieve this functionality using with just one DataGrid,Dataset,DataTable
which contains 2 columns.

Any pointers or sample links will be appreciated.

TIA,
VT
 
V

vijai thoppae

Found the solution by writing a generic class derived from
DataGridTextBoxColumn with the following controls CommandBtn, ComboBox
created upfront in the constructor & based upon a enum value its going to
display the corresponding one accordingly. Here's the class which anybody
can use it.

/// <summary>

/// Derive a custom column style from DataGridTextBoxColumn

/// a) add a Command Button as a member

/// b) track when the Button has focus in Click,Enter and Leave events

/// </summary>

public delegate void DGMultiCtrlChanged( int nCurrRow, int nCurrColumn, int
nSelIndex, bool _bEditing );

public enum DGMultiColumnItems

{

e_DGTextCtrl = 0,

e_DGCmbCtrl,

e_DGCmdCtrl

}

public class DataGridMultiCtrlColumn: DataGridTextBoxColumn

{

public KeyPressCmd ColumnButton = null;

public NoKeyUpCombo ColumnComboBox = null;

private int __nRowNum = 0;

private bool _isEditing = false;

private System.Windows.Forms.CurrencyManager _source = null;

DGMultiCtrlChanged __multiCtrlEvent;

private static bool status = true;

DGMultiColumnItems __eMultiColVal = DGMultiColumnItems.e_DGTextCtrl;

public DataGridMultiCtrlColumn(DGMultiCtrlChanged _multiCtrlEvent) : base()

{

__multiCtrlEvent = _multiCtrlEvent;

ColumnButton = new KeyPressCmd();


ColumnButton.Click += new EventHandler(ButtonClick);

ColumnButton.Enter += new EventHandler(ButtonMadeCurrent);

ColumnButton.Leave += new EventHandler(ButtonLeave);

ColumnComboBox = new NoKeyUpCombo();


ColumnComboBox.Leave += new EventHandler(LeaveComboBox);

ColumnComboBox.Enter += new EventHandler(ComboMadeCurrent);

ColumnComboBox.SelectedIndexChanged +=

new System.EventHandler(ComboIndexChanged);

ColumnComboBox.SelectionChangeCommitted +=

new System.EventHandler(ComboStartEditing);

}

public DGMultiColumnItems _MultiColVal

{

get

{

return this.__eMultiColVal;

}

set

{

__eMultiColVal = value;

}

}


private void ButtonClick(object sender, EventArgs e)

{

int _nColNum = ((DataGrid)ColumnButton.Parent).CurrentCell.ColumnNumber;

__multiCtrlEvent(__nRowNum,_nColNum,0,false);

}

private void ButtonMadeCurrent(object sender, EventArgs e)

{

ColumnButton.Visible = true;

}

private void ButtonLeave(object sender, EventArgs e)

{

Invalidate();

ColumnButton.Visible = false;

}

// Combox Box private methods starts here...

private void ComboStartEditing(object sender, EventArgs e)

{

_isEditing = true;

base.ColumnStartedEditing((Control) sender);

}


private void ComboIndexChanged(object sender, EventArgs e)

{

// background data doesnt change until you leave combobox

// so we cant compare our new vs old values

int _nColNum = ((DataGrid)ColumnComboBox.Parent).CurrentCell.ColumnNumber;

int _nSelIndex = ColumnComboBox.SelectedIndex ;

__multiCtrlEvent(__nRowNum,_nColNum,_nSelIndex,false);

}

private void ComboMadeCurrent(object sender, EventArgs e)

{

//_isEditing = true;

if(status)

{

ColumnComboBox.Visible = true;

}

else

{

ColumnComboBox.Visible = false;

}

}


private void LeaveComboBox(object sender, EventArgs e)

{

if(_isEditing)

{

int _nRow, _nColumn;

_nRow = ((DataGrid)ColumnComboBox.Parent).CurrentCell.RowNumber;

_nColumn = ((DataGrid)ColumnComboBox.Parent).CurrentCell.ColumnNumber;

if (_nColumn == (int)ILineEntryType.IILE_eCC)

{

SetColumnValueAtRow(_source, _nRow, ColumnComboBox.Text);

}

else

{

if(((DataGrid)ColumnComboBox.Parent)[_nRow,0] is System.DBNull)

{ // DONT NEED AS IT IS NOW INITED WHEN ADDED USING BUTTON

}

}

_isEditing = false;

Invalidate();

}

ColumnComboBox.Hide();

}



protected override void Edit(System.Windows.Forms.CurrencyManager source,
int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string
instantText, bool cellIsVisible)

{

base.Edit(source,rowNum, bounds, readOnly, instantText , cellIsVisible);

__multiCtrlEvent(rowNum,_0,0,true);

if ( (_MultiColVal == DGMultiColumnItems.e_DGCmdCtrl) ||

(_MultiColVal == DGMultiColumnItems.e_DGCmbCtrl)

)

{

__nRowNum = rowNum;

_source = source;

if (_MultiColVal == DGMultiColumnItems.e_DGCmbCtrl)

{

ColumnComboBox.Parent = this.TextBox.Parent;

ColumnComboBox.Location = this.TextBox.Location;

ColumnComboBox.Size = new Size(this.TextBox.Size.Width,
ColumnComboBox.Size.Height);

ColumnComboBox.SelectedIndexChanged -= new
System.EventHandler(ComboIndexChanged);

ColumnComboBox.Text = this.TextBox.Text;

ColumnComboBox.SelectedIndexChanged += new
System.EventHandler(ComboIndexChanged);

this.TextBox.Visible = false;

ColumnComboBox.Visible = true;

ColumnComboBox.BringToFront();

ColumnComboBox.Focus();

}

else if(_MultiColVal == DGMultiColumnItems.e_DGCmdCtrl)

{

ColumnButton.Parent = this.TextBox.Parent;

Point pt1 = TextBox.Location;

pt1.X = (pt1.X + 165);

ColumnButton.Location = pt1;//this.TextBox.Location;

Point pt2 = new Point(TextBox.Size.Width,TextBox.Size.Height);

pt2.X = pt2.X - 165;

ColumnButton.Size = new Size(pt2);//(this.TextBox.Size.Width,
TextBox.Size.Height);

ColumnButton.BackColor = System.Drawing.SystemColors.Control;

ColumnButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;

ColumnButton.Text = "...";

this.TextBox.Visible = false;

ColumnButton.Visible = true;

ColumnButton.BringToFront();

ColumnButton.Focus();

}

}

else

this.TextBox.Visible = true;

}

}

public class NoKeyUpCombo : ComboBox

{

const int WM_KEYUP = 0x101;

protected override void WndProc(ref System.Windows.Forms.Message m)

{

if(m.Msg == WM_KEYUP)

{

//ignore keyup to avoid problem with tabbing & dropdownlist;

return;

}

base.WndProc(ref m);

}

} // NoKeyUpCombo

/// <summary>

/// This class is useful to handle WndProc messages generated by Command
Button control

/// </summary>

public class KeyPressCmd : Button

{

const int WM_KEYUP = 0x101;

protected override void WndProc(ref System.Windows.Forms.Message m)

{

if(m.Msg == WM_KEYUP)

{

//ignore keyup to avoid problem with tabbing & dropdownlist;

return;

}

base.WndProc(ref m);

}

} // KeyPressCmd

Thanks,

Vijai
 

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