Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Actualizar datos en componente (https://www.clubdelphi.com/foros/showthread.php?t=73593)

dalyla2010 03-05-2011 19:56:57

Actualizar datos en componente
 
Hola buen dia a todos,

Resulta que modifique el TComboBox para agregarle la propiedad ValueIndex, es decir, en vez de yo darle el ItemIndex, como posicion autoincremental, le doy un valor, por ejemplo:

Paises[0] := 'Mexico';
Paises[1] := 'Holanda';

Hasta aqui sabemos que mexico tiene el index 0, holanda el 1. Si yo quiero seleccionar Holanda pongo:

Paises.ItemIndex := 1;

pero yo no lo quiero buscar por el ItemIndex, porque tengo una tabla en una BD que me dice que es el numero "840", entonces segun, este componente que modifique haria lo siguiente:

Paises.ValueIndex := '840';

entonces en el combo, el itemindex es 1, y se muestra Holanda.

Lo raro es que la primera vez que hago esto si se actualiza el combo, si hago otra busqueda, se queda en blanco, y quizas en otra ya me aparesca, no se como hacer para que se actualize.

Porque si lo checo con un breakpoint, me dice el valor, el ItemIndex y ValueIndex correcto pero la pantalla no se refresca o actualiza.

Segun yo el refresh o el update no me funciono.

Alguna idea?:D

oscarac 03-05-2011 20:16:37

no entendi muy bien...
disculpa pero que tiene que ver el '840' ?
o es que los paises los quieres sacar de la tabla?

dalyla2010 03-05-2011 20:29:33

codigo
 
Digamos que quiero hacer el combobox como los de las paginas web. en mi BD de paises se muestra asi:

IdPais nombre
803 Mexico
804 Holanda

Este es un ejemplo que se me ocurrio. pero con varios otros conceptos ocupo buscarlo por el ID y no por el consecutivo del combo. Por decir en la tabla de arriba mis ID's comienzan con 800 y no con 0 y se puede brincar del 804 al 820. Pero como mejor ejemplo quiero el combo como el tipo web.

<select name= "cbpais".... value="803">Mexico</select>
y en web cuando hago un $_REQUEST['cbpais'] me devuelve el 803 y no el 1 o el 0.

Igual abajo pongo el codigo, por si encuentran algun error. Lo que hago es que voy creando un arreglo aparte para consultar el valor de los ID's

Código Delphi [-]
unit ComboBoxValue;
interface
uses
  SysUtils, Classes, Controls, StdCtrls;
type
  TComboBoxValue = class(TComboBox)
  private
    valores: array of string;
    { Private declarations }
  protected
    function GetValueIndex:string;
    procedure SetValueIndex(valor:string);
    { Protected declarations }
  public
    procedure Add(S, V:string);
    property ValueIndex :string  read GetValueIndex  write SetValueIndex;
    { Public declarations }
  published
    { Published declarations }
  end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('Samples', [TComboBoxValue]);
end;
procedure TComboBoxValue.Add(S, V: string);
begin
SetLength(valores, ItemCount);
AddItem(S, self);
SetLength(valores, ItemCount);
valores[ItemCount-1] := V;
end;
procedure TComboBoxValue.SetValueIndex(valor:string);
var i:integer;
begin
for I := 0 to ItemCount - 1 do
  begin
    if valores[i] = valor then
       ItemIndex := i;
  end;
Changed;
end;
function TComboBoxValue.GetValueIndex:string;
begin
if ItemCount > 0 then
  result := valores[ItemIndex]
else
  result := 'null';
end;
End.

ecfisa 03-05-2011 21:15:06

Hola dalyla2010.

A ver si entendí lo que buscas hacer. ¿ Vos querés utilizar como índice a los ID de los países en lugar de la propiedad ItemIndex del ComboBox ?

Un saludo.

ecfisa 03-05-2011 22:48:23

Hola dalyla2010.

Fijate si esto te sirve o te ayuda a hacer lo que estas buscando. El ejemplo usa un TComboBox, TDBLookupCombobox, TDataSource y un DataSet,
también agrego la propiedad ItemIndex_ID.
Código Delphi [-]
...
type
  TComboBox = class(StdCtrls.TComboBox)
  private
    procedure SetItem_ID(Item_ID: Integer);
    function GetItem_ID: Integer;
  public
    property ItemIndex_ID: Integer read GetItem_ID write SetItem_ID;
  end;
  TForm1 = class(TForm)
    //Aca tu DataSet
    DataSource1: TDataSource;
    ComboBox1: TComboBox;
    DBLookupComboBox1: TDBLookupComboBox;
    procedure FormShow(Sender: TObject);
    procedure DBLookupComboBox1CloseUp(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    ...
  end;
var
  Form1: TForm1;

implementation

(* TComboBox *)
function TComboBox.GetItem_ID: Integer;
begin
  Result:= Integer(Items.Objects[ItemIndex]);
end;

procedure TComboBox.SetItem_ID(Item_ID: Integer);
begin
  if Item_ID in [0.. Items.Count-1] then
    ItemIndex:= Items.IndexOfObject(TObject(Item_ID));
end;

(* TForm1 *)
// Cargar el ComboBox
procedure TForm1.FormShow(Sender: TObject);
begin
  while not DataSet.Eof do
  begin
    ComboBox1.Items.AddObject(DataSet.FieldByName('NOMBRE_PAIS').AsString,
     TObject(DataSet.FieldByName('PAIS_ID').AsInteger));
    DataSet.Next;
  end;
end;

// Pone en ComboBox1 la selección realizada
procedure TForm1.DBLookupComboBox1CloseUp(Sender: TObject);
begin
  ComboBox1.ItemIndex_ID:= DataSet.FieldByName('PAIS_ID').AsInteger;
end;

// Pone en DBLookupComboBox la selección realizada
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  DBLookupComboBox1.KeyValue:= ComboBox1.ItemIndex_ID;
end;
...
Si hay algo en lo que no me expliqué bién, ajusto el ejemplo para alguna tabla que venga con Delphi y te adjunto los archivos.

Un saludo.

dalyla2010 04-05-2011 01:46:07

Mmm la verdad es que no quiero llenar de componentes la forma y lo que quiero yo es un nuevo componente, un tcombobox con un arreglo dentro de el. Asi como si tuviera dos columnas, solo que no se muestra.

Porque lo ocupo asi en varios formularios. Por decir el formulario de clientes, ocupo el estatus, la colonia, el municipio, el estado, y otras clasificaciones que terminan siendo como 8 combobox, mas 8 datasource, mas 8 tablas, mas 8 dblookupcombobox (o algo asi).

Y como yo lleno estos combos con un componente, asi que lo limpio y lo uso para llenar otro y asi. y con un componente no tengo que estar programando esto cada vez. No se si explique bien mi necesidad.

Pero muchas gracias por tu respuesta :D

ecfisa 04-05-2011 02:21:49

Cita:

Asi como si tuviera dos columnas, solo que no se muestra.
Hola dalyla2010.

Es precisamente como queda el Combobox del ejemplo: Una columna para el nombre del país y otra para su ID.
Es decir que tenés un 'nuevo ItemIndex' que funciona con los ID de los paises en lugar de la posición del item en el combo.

Tendrás que ver eso sí, como implementar la propiedad ItemIndex_ID en tu nuevo componente.

Un saludo.

dalyla2010 04-05-2011 18:29:27

Lo intentare
 
Haber si te entendi, lo que pasa es que nunca he insertado un object, el object seria como un tag, o una variable al mismo nivel del row en el array del combo. Bueno cambiare mi array por el object haber que pasa y comento.

al igual mi codigo me funciona la primera vez, pero la segunda vez ke cambio la posicion del index no me funciona. Osea no se actualiza. Espero no me pase con el object.

Gracias, comento cuando lo pruebe :D

dalyla2010 04-05-2011 19:07:53

No me funciono :s el combo si se lleno, pero no me funciona el SET, el GET no lo he probado.

Modifique para que los resultados sean strings. no me marca error pero igual no hace lo que ocupo. O bien si alguien me puede ayudar a corregir mi codigo se lo agradesco.

Los dos codigos no son muy diferentes solo que yo uso un array y ecfisa usa objetos. Aun asi gracias :)

Código Delphi [-]
 
unit ComboBoxValue;
interface
uses
  SysUtils, Classes, Controls, StdCtrls;
type
  TComboBoxValue = class(TComboBox)
  private
    { Private declarations }
  protected
    function GetValueIndex:string;
    procedure SetValueIndex(valor:string);
    { Protected declarations }
  public
    procedure Add(S, V:string);
    property ValueIndex :string  read GetValueIndex  write SetValueIndex;
    { Public declarations }
  published
    { Published declarations }
  end;
procedure Register;
implementation
 
procedure Register;
begin
  RegisterComponents('Samples', [TComboBoxValue]);
end;
procedure TComboBoxValue.Add(S, V: string);
begin
Items.AddObject(S, TObject(V));
end;
 
procedure TComboBoxValue.SetValueIndex(valor:string);
var i:integer;
begin
for I := 0 to ItemCount - 1 do
  begin
    if Items.Objects[i] = TObject(valor) then
       ItemIndex := Items.IndexOfObject(TObject(valor));
  end;
end;
 
function TComboBoxValue.GetValueIndex:string;
begin
if ItemCount > 0 then
  Result:= string(Items.Objects[ItemIndex]) 
else
  result := '1';
end;
 
End.

dalyla2010 04-05-2011 19:39:30

Encontre problema pero no solucion
 
El problema que tengo en mi componente es cuando asigno a Text

Por decir quier inicializar mi formulario y si lo hago asi:

Combo.Text := '';

Me da problemas con mi componente y no lo manda a itemIndex := -1;

y de ahi en adelante el combo responde despues de que entro a el con un clic o algo ya vuelve a funcionar. Pero no me respeta lo que hago por codigo antes de eso.

Sin embargo si yo le pongo :

Combo.ItemIndex := -1;

Funciona correctamente. Supongo que tengo que heredar la propiedad Text y al no estar en la lista lo deje en Itemindex -1.

Saludos:D


La franja horaria es GMT +2. Ahora son las 02:54:00.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi