Forum > General
Assign event on runtime.
fredycc:
hi, I had a problem when I tried to display data into a combobox and retrieve the Id for the data selected some times is numeric anothers alphanumeric, but I found a piece of code that helps me displaying my data for columns; but I need write the same code for each comobobox into DrawItem, How Can I write just one time this event and assign it on runtime maybe? %), the code is :
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
var
sValor, sTodo: string;
i, iPos: Integer;
rc: TRect;
AnchoColumna: array[0..3] of Integer;
begin
ComboBox1.Canvas.FillRect( ARect );
sTodo := ComboBox1.Items[Index];
// Establecemos el ancho de las columnas
AnchoColumna[0] := 0;
AnchoColumna[1] := 200; // Ancho de la columna 1
AnchoColumna[2] := 300; // Ancho de la columna 2
AnchoColumna[3] := 0; // Ancho de la columna 3
// Leemos el texto de la primera columna
iPos := Pos( ';', sTodo );
sValor := Copy( sTodo, 1, iPos - 1 );
for i := 0 to 2 do
begin
// Dibujamos la primera columna
rc.Left := ARect.Left + AnchoColumna + 2;
rc.Right := ARect.Left + AnchoColumna[i+1] - 2;
rc.Top := ARect.Top;
rc.Bottom := ARect.Bottom;
// Escribimos el texto
Combobox1.Canvas.TextRect( rc, rc.Left, rc.Top, sValor );
// Dibujamos las líneas que separan las columnas
if i < 3 then
begin
Combobox1.Canvas.MoveTo( rc.Right, rc.Top );
Combobox1.Canvas.LineTo( rc.Right, rc.Bottom );
end;
// Leemos el texto de la segunda columna
sTodo := Copy( sTodo, iPos + 1, Length( sTodo ) - iPos );
iPos := Pos( ';', sTodo );
sValor := Copy( sTodo, 1, iPos - 1 );
end;
end;
//Add Items to ComboBox
ComboBox1.Style:= csOwnerDrawVariable;
with Combobox1.Items do
begin
Add( 'DOLLAR;USD1;' );
Add( 'PESO;MX1;' );
Add( 'EURO;EUR;' );
Add( 'YEN;YEN;' );
end;
eny:
I'd say in true OO style :)
Create a new class that does all the recurring actions.
Use for example the Combobox as a parameter in the new class constructur.
And define a method in the new class of type TDrawItemEvent that you assign to the Combobox OnDrawItem event.
Forgot something: the Decorator pattern.
mas steindorff:
first check out these post for dynamic components
http://lazarus.freepascal.org/index.php/topic,8912.0.html
be sure to call each component's create()
As far as events, just set then to the function you have already written like this for a timer.
mytimer.ontimer := @MainForm.OnTimer;
when the event fires, your code will be run
eny:
Couldn't resist :D
This gives you the basic idea.
--- Code: ---unit CurrencyComboBoxDecorator;
{$mode objfpc}
interface
uses
strutils,
Controls, StdCtrls, Classes, SysUtils;
type
{ TCurrencyComboBoxDecorator }
TCurrencyComboBoxDecorator = class
private
FCombo: TComboBox;
AnchoColumna: array[0..3] of Integer;
procedure InitializeCombo;
procedure OnDrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState);
public
constructor Create(pComboBox: TComboBox);
destructor Destroy; override;
property Combo: TComboBox read FCombo;
end;
implementation
{ TCurrencyComboBoxDecorator }
constructor TCurrencyComboBoxDecorator.Create(pComboBox: TComboBox);
begin
// Store combobox we want to decorate locally
FCombo := pComboBox;
// Establecemos el ancho de las columnas
AnchoColumna[0] := 0;
AnchoColumna[1] := 200; // Ancho de la columna 1
AnchoColumna[2] := 300; // Ancho de la columna 2
AnchoColumna[3] := 0; // Ancho de la columna 3
// And set up the combobox the way we want
InitializeCombo;
end;
destructor TCurrencyComboBoxDecorator.Destroy;
begin
Combo.OnDrawItem := nil;
inherited Destroy;
end;
procedure TCurrencyComboBoxDecorator.InitializeCombo;
begin
with Combo.Items do
begin
Clear;
Add( 'DOLLAR;USD1;' );
Add( 'PESO;MX1;' );
Add( 'EURO;EUR;' );
Add( 'YEN;YEN;' );
end;
Combo.Style := csOwnerDrawVariable;
Combo.Text := '';
Combo.OnDrawItem := @OnDrawItem;
end;
procedure TCurrencyComboBoxDecorator.OnDrawItem(Control: TWinControl; Index: Integer; ARect: TRect;
State: TOwnerDrawState);
var
i : Integer;
rc: TRect;
begin
Combo.Canvas.FillRect( ARect );
for i := 0 to high(AnchoColumna)-1 do
begin
// Dibujamos la primera columna
rc.Left := ARect.Left + AnchoColumna[i] + 2;
rc.Right := ARect.Left + AnchoColumna[i+1] - 2;
rc.Top := ARect.Top;
rc.Bottom := ARect.Bottom;
// Escribimos el texto
Combo.Canvas.TextRect( rc, rc.Left, rc.Top, ExtractWord(i+1,Combo.Items[Index], [';']) );
// Dibujamos las líneas que separan las columnas
Combo.Canvas.MoveTo( rc.Right, rc.Top );
Combo.Canvas.LineTo( rc.Right, rc.Bottom );
end;
end;
end.
--- End code ---
In your form's creator, just add something like this:
--- Code: --- decorator: TCurrencyComboBoxDecorator; // Form variable
...
decorator := TCurrencyComboBoxDecorator.Create(ComboBox1);
--- End code ---
fredycc:
wow, thanks a lot eny & mas steindorff; fantastic eny, you save me ;D
Navigation
[0] Message Index
[#] Next page