combobox inside datagrid

R

Rick

hi group!!

my question is in a datagrid i have 3 columns, 2 columns are just text,
third is type combobox, can i load in that combobox values from other table
that is not the same the grid displays? (if true, how can i do it?)

Thanks!!
 
B

Bart Mermuys

Hi,

Rick said:
hi group!!

my question is in a datagrid i have 3 columns, 2 columns are just text,
third is type combobox, can i load in that combobox values from other
table that is not the same the grid displays? (if true, how can i do it?)

Are you using DataGrid or DataGridView (NET2.0).
A DataGrid doesn't come with a DataGridComboBoxColumnStyle (but you can find
sourcecode on the net).
A DataGridView comes with a DataGridViewComboBoxColumn

In both cases it should be possible to assign data from another DataTable.
Set ComboBox(Column) DataSource/DataMember to another table and set
ValueMember to a column that has the same data as the master column.


HTH,
Greetings
 
C

Cyr1dian

I don't know about .Net FW2.0, but if ur using an older version (as most
of us still are) there's a plethora of solution out there... most of which
don't seem to work for most people (including myself). Here's one that
worked for me - I DID NOT WRITE IT (kudos to the person who did, but I
can't remember where I got it):

This solution let's you add a combobox that is filled by a datasource, it
is commonly used for foreign key fields where it is convenient to display
text where number are actually inserted. I don't know what you exactly
wish to achieve but this is can be adapted to suit most situations I think.

There are 3 parts to this listed below in this order:
1) DataGridComboBoxColumn.cs
2) myComboBox.cs
3) implementation code


=========================
DataGridComboBoxColumn.cs
=========================

using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace YourNameSpace
{
public class DataGridComboBoxColumn : DataGridTextBoxColumn
{
public myComboBox myComboBox;
private System.Windows.Forms.CurrencyManager _currencyManager;
private int _rowNum;
private bool _Editing;

// Constructor, create our own customized Combobox
public DataGridComboBoxColumn()
{
_currencyManager = null;
_Editing = false;

// Create our own customized Combobox, which is used in the DataGrid
// DropDownList: The user cannot directly edit the text portion.
// The user must click the arrow button to display the
// list portion.
// DropDown: The text portion is editable. The user must click
// the arrow button to display the list portion.
// Simple: The text portion is editable. The list portion is
// always visible.
myComboBox = new myComboBox();
myComboBox.DropDownStyle = ComboBoxStyle.DropDownList;

// My own Combobox subscribes to the Leave Event. It occurs when the
// input focus leaves the ComboBox.
this.myComboBox.Leave +=
new System.EventHandler(LeaveComboBox);

// My own Combobox subscribes to the SelectionChangeCommitted Event.
// It occurs when the selected item has changed and that change
// is committed (save the changed data to the DataGrid TextBox).
this.myComboBox.SelectionChangeCommitted +=
new System.EventHandler(SelectionChangeCommit);
}

// Make current Combobox invisible when user scrolls
// the DataGrid control using the ScrollBar.
private void HandleScroll(Object sender, EventArgs e)
{
if (myComboBox.Visible)
{
myComboBox.Hide();
}
}

// The ColumnStartedEditing method allows the DataGrid
// to show a pencil in the row header indicating the row
// is being edited. (base is the parent DataGridTextBoxColumn)
private void SelectionChangeCommit(Object sender, EventArgs e)
{
_Editing = true;
base.ColumnStartedEditing((System.Windows.Forms.Control) sender);
}

// Handle Combobox Behaviour when Focus leaves the Combobox.
private void LeaveComboBox(Object sender, EventArgs e)
{
if (_Editing)
{
// Set the Combobox ValueMember to the current RowColumn
// when the Focus leaves the Combobox.
SetColumnValueAtRow(_currencyManager, _rowNum, myComboBox.Text);
_Editing = false;

// Redraws the column
Invalidate();
}
// Hide the current Combobox when Focus on Combobox is loosen
myComboBox.Hide();

// Let current Combobox visible when user scrolls
// the DataGrid control using the ScrollBar.
this.DataGridTableStyle.DataGrid.Scroll += new
System.EventHandler(HandleScroll);
}

// The SetColumnValueAtRow method updates the bound
// DataTable "Titles" with the ValueMember
// for a given DisplayMember = myComboBox.Text from the Combobox.
protected override void SetColumnValueAtRow
(CurrencyManager source, int rowNum, Object value)
{
Object tbDisplay = value;
DataView dv = (DataView)this.myComboBox.DataSource;
int rowCount = dv.Count;
int i = 0;
Object cbDisplay;
Object cbValue;

// Loop through the Combobox DisplayMember values
// until you find the selected value, then read the
// ValueMember from the Combobox and update it in the
// DataTable "Titles"
while (i < rowCount)
{
cbDisplay = dv[this.myComboBox.DisplayMember];

if ((cbDisplay != DBNull.Value) &&
(tbDisplay.Equals(cbDisplay)))
{
break;
}
i += 1;
}
if (i < rowCount)
{
cbValue = dv[this.myComboBox.ValueMember];
}
else
{
cbValue = DBNull.Value;
}
base.SetColumnValueAtRow(source, rowNum, cbValue);
}

// The GetColumnValueAtRow method updates the bound
// Combobox with the DisplayMember
// for a given Row Number = rowNum from the DataTable "Titles".
protected override Object GetColumnValueAtRow
(CurrencyManager source, int rowNum)
{
// Get the ValueMember from the DataTable "Titles"
Object tbValue = base.GetColumnValueAtRow(source, rowNum);

// Associate a DataView to the Combox, so we can search
// the DisplayMember in the Combox corresponding to the
// ValueMember from the DataTable "Titles"
DataView dv = (DataView)this.myComboBox.DataSource;
int rowCount = dv.Count;
int i = 0;
Object cbValue;

// Loop through the Combox Entries and search the DisplayMember
while (i < rowCount)
{
cbValue = dv[this.myComboBox.ValueMember];
if ((cbValue != DBNull.Value) &&
(tbValue != DBNull.Value) &&
(tbValue.Equals(cbValue)))
{
break; // We found the DisplayMember - exit the Loop
}
i += 1;
}

// If we are within the Combox Entries, return now the DisplayMember
// for the found ValueMember above. If we are at the End of the Combox
// Entries, return NULL
if (i < rowCount)
{
return dv[this.myComboBox.DisplayMember];
}
else
{
return DBNull.Value;
}
}

// The Edit event is raised when the user sets the focus to the cell
// containing the combobox. In this event the dimensions of the combobox
// are set and an event handler is assigned to handle scrolling of the
combobox.
protected override void Edit(
CurrencyManager source,
int rowNum,
Rectangle bounds,
bool readOnly,
string instantText,
bool cellIsVisible)
{
base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);

// Set current Rownum and Postion Manager
_rowNum = rowNum;
_currencyManager = source;

// Calculate Location of the Combox relative to the TextBox
// of the DataGrid which have the Focus
Point NewLoc;
NewLoc = this.TextBox.Location;
NewLoc.X -= 3;
NewLoc.Y -= 3;
myComboBox.Location = NewLoc;

// Attach the Combobox to the same Parent Control
// as the TextBox of the DataGrid
myComboBox.Parent = this.TextBox.Parent;

// Position the Combox at the same Location as the TextBox
myComboBox.Size = new Size(this.TextBox.Size.Width + 3,
myComboBox.Size.Height);

// Select the Entry in the Combobox corresponding to the Text in
// in the TextBox.
myComboBox.SelectedIndex =
myComboBox.FindStringExact(this.TextBox.Text);
// myComboBox.Text = this.TextBox.Text;

// Make the TextBox invisible and then show the Combobox
this.TextBox.Visible = false;
myComboBox.Visible = true;
myComboBox.BringToFront();
myComboBox.Focus();

// Make Combobox invisible id User scrolls uo or down the DataGrid
this.DataGridTableStyle.DataGrid.Scroll += new
System.EventHandler(HandleScroll);
}

// The Commit method can be used to put the Combomox ValueMember
// into the TextBox ValueMember. This can be handled in the
// LeaveComboBox EventHandler as well.
protected override bool Commit(
System.Windows.Forms.CurrencyManager dataSource,int rowNum)
{
if (_Editing)
{
_Editing = false;
SetColumnValueAtRow(dataSource, rowNum, myComboBox.Text);
}
return true;
}
}
}


=============
myComboBox.cs
=============

// The NoKeyUpCombo class derives a new ComboBox whose WndProc
// method is overridden. This is required to address issues when
// It is this derived combobox that is added to the datagrid.
// When you TAB trough the DataGrid and you reach the DropDown Combobox
// the Focus is immediately moved to the next Column.
using System;

namespace JNS_WinClient
{
public class myComboBox: System.Windows.Forms.ComboBox
{
private const int WM_KEYUP = 0x101;

// The WndProc method corresponds exactly to the Windows WindowProc
function.
// For more information about processing Windows messages, see the
WindowProc
// function documentation in the Windows Platform SDK reference located
in
// the MSDN Library.
protected override void WndProc(ref System.Windows.Forms.Message
theMessage)
{
// Ignore KeyUp event to avoid problem with tabbing the dropdown.
if (theMessage.Msg == WM_KEYUP)
{
return;
}
else
{
base.WndProc(ref theMessage);
}
}
}
}


===================
Implementation code (use in OnLoad)
===================

//Set up combobox in datagrid
//dgFields is a datagrid
/*
DataGridComboBoxColumn myDGCBC = new DataGridComboBoxColumn();
myDGCBC.MappingName="FT_ID";
myDGCBC.HeaderText="Type";
myDGCBC.Width=100;
myDGCBC.myComboBox.DataSource=dsProxyJNS.tbl_FieldTypes.DefaultView;
myDGCBC.myComboBox.DisplayMember = "FT_Name";
myDGCBC.myComboBox.ValueMember = "FT_ID";
dgFields.TableStyles[0].PreferredRowHeight=myDGCBC.myComboBox.Height;
dgFields.TableStyles[0].GridColumnStyles.Add(myDGCBC);
*/



If you have any problems look for one of the many other solutions out
there.

HTH,
Cyr1dian
 

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