Thread View: borland.public.delphi.database.dotnet
1 messages
1 total messages
Started by Brigitte Spatz
Tue, 15 Aug 2006 15:39
combo box in data grid
Author: Brigitte Spatz
Date: Tue, 15 Aug 2006 15:39
Date: Tue, 15 Aug 2006 15:39
235 lines
8457 bytes
8457 bytes
I have adapted the C# code from
http://msdn.microsoft.com/msdnmag/issues/03/08/DataGrids/default.aspx for
a data grid combo box column and added it to my data grid. I donβt get an
error but the column is simply not displayed (but if I query
VisibleColumnCount I get 7, which means it *should* be there, the row
height is also visibly larger). Can anybody spot what I might be
missing/doing wrong? TIA.
// init
ts := DataGridTableStyle.Create;
dc1 := DataGridTextBoxColumn.Create;
dc2 := DataGridBoolColumn.Create;
dc3 := DataGridTextBoxColumn.Create;
dc4 := DataGridTextBoxColumn.Create;
dc5 := DataGridTextBoxColumn.Create;
dc6 := DataGridTextBoxColumn.Create;
dc7 := DataGridComboBoxColumn.Create;
ts.MappingName := 'ODM';
ts.AlternatingBackColor := color.WhiteSmoke;
// column 1 β ordinary text box:
dc1.MappingName := 'fld_odmID';
dc1.HeaderText := 'ID';
dc1.Alignment := HorizontalAlignment.left;
dc1.NullText := '';
dc1.Width := 45;
<snip β columns 2 β 6 are all text boxes>
// column 7 β the combo box:
SetLookupBinding(dc7.Combobx, 'fld_LastName', 'fld_ContactID',
ds.Tables['contact']); //see procedure below
dc7.HeaderText := 'Ansprechpartner';
dc7.Alignment := horizontalalignment.Left;
dc7.NullText := '';
dc7.Width := 150;
ts.PreferredRowHeight := dc7.Combobx.Height + 1;
ts.GridColumnStyles.Add(dc1);
ts.GridColumnStyles.Add(dc3);
ts.GridColumnStyles.Add(dc4);
ts.GridColumnStyles.Add(dc5);
ts.GridColumnStyles.Add(dc2);
ts.GridColumnStyles.Add(dc6);
ts.GridColumnStyles.add(dc7);
datagrid1.TableStyles.Add(ts);
procedure SetLookupBinding(combobx: System.Windows.Forms.Combobox;
DisplayColumn, BoundColumn: string; dt: DataTable);
begin
with combobx do
begin
DisplayMember := DisplayColumn;
ValueMember := BoundColumn;
DataSource := dt;
end;
end;
and the new class in a separate unit:
unit DataGridComboBoxColumnU;
interface
uses
System.Windows.Forms, System.Drawing, System.Data;
type
DataGridComboBoxColumn =
class(System.Windows.Forms.DataGridTextBoxColumn)
private
{ Private-Deklarationen }
cm: CurrencyManager;
intCurrentRow: Integer;
cbb: Combobox; // Hosted combobox control
procedure comboBox_Leave(sender: System.Object; e: EventArgs );
procedure DataGrid_Scroll(sender: System.Object; e: EventArgs);
protected
procedure Edit(source: System.Windows.Forms.CurrencyManager;
rowNum: Integer; bounds: System.Drawing.Rectangle; readOnly: Boolean;
instantText: string; cellIsVisible: Boolean); override;
function GetColumnValueAtRow(source:
System.Windows.Forms.CurrencyManager;
rowNum: Integer): System.Object; override;
procedure SetColumnValueAtRow(source:
System.Windows.Forms.CurrencyManager;
rowNum: Integer; value: System.Object); override;
public
constructor Create;
function Combobx: Combobox;
end;
implementation
constructor DataGridComboBoxColumn.Create;
{Constructor - create combobox, register selection change event handler,
register lose focus event handler}
begin
inherited Create;
// Create combobox and force DropDownList style:
cbb := Combobox.Create;
cbb.DropDownStyle := ComboBoxStyle.DropDownList;
// Add event handler for notification when combobox loses focus:
Include(Self.cbb.Leave, Self.comboBox_Leave);
end;
function DataGridComboBoxColumn.Combobx: Combobox;
begin
Result := cbb;
end;
procedure DataGridComboBoxColumn.comboBox_Leave(sender: System.Object; e:
EventArgs );
{On combobox losing focus, set the column value, hide the combobox,
and unregister scroll event handler}
var
str: string;
rowView: DataRowView;
begin
rowView := DataRowView(cbb.SelectedItem);
str := string(rowView.Row[cbb.DisplayMember]);
SetColumnValueAtRow(cm, intCurrentRow, str);
Invalidate;
cbb.Hide;
Exclude(DataGridTableStyle.DataGrid.Scroll, DataGrid_Scroll);
end;
procedure DataGridComboBoxColumn.Edit(source:
System.Windows.Forms.CurrencyManager;
rowNum: Integer; bounds: System.Drawing.Rectangle; readOnly: Boolean;
instantText: string; cellIsVisible: Boolean);
// On edit, add scroll event handler, and display combobox
var rect: Rectangle;
begin
inherited Edit(source, rowNum, bounds, readOnly, instantText,
cellIsVisible);
if (not readOnly and cellIsVisible) then
begin
// Save current row in the DataGrid and currency manager
// associated with the data source for the DataGrid
intCurrentRow := rowNum;
cm := source;
// Add event handler for DataGrid scroll notification
include(DataGridTableStyle.DataGrid.Scroll, DataGrid_Scroll);
// Site the combobox control within the current cell
cbb.Parent := TextBox.Parent;
rect := DataGridTableStyle.DataGrid.GetCurrentCellBounds;
cbb.Location := rect.Location;
cbb.Size := Size.Create(TextBox.Size.Width, cbb.Size.Height);
// Set combobox selection to given text
cbb.SelectedIndex := cbb.FindStringExact(TextBox.Text);
// Make the combobox visible and place on top textbox control
cbb.Show;
cbb.BringToFront;
cbb.Focus;
end;
end;
function DataGridComboBoxColumn.GetColumnValueAtRow(
source: System.Windows.Forms.CurrencyManager; rowNum: Integer):
System.Object;
{Given a row, get the value member associated with a row. Use the
value member to find the associated display member by iterating
over bound data source}
var
obj: System.&Object;
dv: DataView;
i: Integer;
begin
// Given a row number in the DataGrid, get the display member
obj := inherited GetColumnValueAtRow(source, rowNum);
// Iterate through the data source bound to the ColumnComboBox
cm :=
CurrencyManager(DataGridTableStyle.DataGrid.BindingContext[cbb.DataSource]);
// Assumes the associated DataGrid is bound to a DataView or
// DataTable
dv := DataView(cm.List);
for i := 0 to dv.Count - 1 do
if (obj.Equals(dv[i][cbb.ValueMember])) then
break;
// If set item was found return corresponding value,
// otherwise return DbNull.Value
if (i < dv.Count) then
Result := dv[i][cbb.DisplayMember];
Result := DBNull.Value;
end;
procedure DataGridComboBoxColumn.SetColumnValueAtRow(
source: System.Windows.Forms.CurrencyManager; rowNum: Integer;
value: System.Object);
{Given a row and a display member, iterate over bound data source to
find the associated value member. Set this value member.}
var
s: System.&Object;
dv: DataView;
i: Integer;
begin
s := value;
// Iterate through the data source bound to the ColumnComboBox:
cm := CurrencyManager(
DataGridTableStyle.DataGrid.BindingContext[cbb.DataSource]);
// Assumes the associated DataGrid is bound to a DataView or
// DataTable
dv := DataView(cm.List);
for i := 0 to dv.Count - 1do
if (s.Equals(dv[i][cbb.DisplayMember])) then
break;
if i < dv.Count then
s := dv[i][cbb.ValueMember]
else
s := DBNull.Value;
inherited SetColumnValueAtRow(source, rowNum, s);
end;
procedure DataGridComboBoxColumn.DataGrid_Scroll(sender: System.Object; e:
EventArgs);
// On DataGrid scroll, hide the combobox
begin
cbb.Hide;
end;
end.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads