Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Simular dos radiobuttons con Checkbox (https://www.clubdelphi.com/foros/showthread.php?t=34868)

TriLoCBA 24-08-2006 02:36:14

Simular dos radiobuttons con Checkbox
 
Necesito simular el efecto de seleccion unica que poseen los radiobutton con un par de checkbox (Ch1 y Ch2), y no consigo que funcionen :confused::

Código Delphi [-]
procedure TForm1.Ch1Click(Sender: TObject);
begin
  Ch1.Checked:=True;
  if Ch2.Checked then Ch2.Checked:=False;
end;

procedure TForm1.Ch2Click(Sender: TObject);
begin
  Ch2.Checked:=True;
  if Ch1.Checked then Ch1.Checked:=False;
end;

Desde ya muchas gracias por vuestra ayuda...

Un abrazo...

TriloCba

roman 24-08-2006 02:51:58

Intenta así:

Código Delphi [-]
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  if CheckBox1.Checked then
  begin
    CheckBox2.OnClick := nil;
    CheckBox2.Checked := false;
    CheckBox2.OnClick := CheckBox2Click;
  end;

  CheckBox1.Checked := true;
end;

procedure TForm1.CheckBox2Click(Sender: TObject);
begin
  if CheckBox2.Checked then
  begin
    CheckBox1.OnClick := nil;
    CheckBox1.Checked := false;
    CheckBox1.OnClick := CheckBox1Click;
  end;

  CheckBox2.Checked := true;
end;

// Saludos

seoane 24-08-2006 02:54:59

Vamos a ver que te parece esta solución. Usamos un solo evento OnClick para los dos checkbox, y dento colocamos esto:

Código Delphi [-]
procedure TForm1.Ch1Click(Sender: TObject);
begin
  // Solo hay problemas cuando los dos estan marcados
  if Ch2.Checked and Ch1.Checked  then
    // Desmarcamos el checkbox que no nos llamo
    if Sender = Ch1 then
      Ch2.Checked:= FALSE
    else
      Ch1.Checked:= FALSE;
end;

PD: ¿Porque no usas radiobuttons? si quieres tener la opción de no marcar ninguno, siempre puedes añadir otro radiobutton con el caption "Ninguno de las anteriores" :)

roman 24-08-2006 03:00:40

Cita:

Empezado por seoane
si quieres tener la opción de no marcar ninguno, siempre puedes añadir otro radiobutton con el caption "Ninguno de las anteriores" :)

¿Y si no quiere? Es decir, tal como pones, no se imita exactamente el comportamiento de dos radiobuttons ya que justamente puedes desmarcar ambos. Quizá sólo sea una razón estética.

// Saludos

egostar 24-08-2006 03:10:50

Honor a quien honor merece, Roman, eres un maestro.

Me pongo de pie.

Saludos.

seoane 24-08-2006 03:22:12

Cita:

Empezado por roman
¿Y si no quiere? Es decir, tal como pones, no se imita exactamente el comportamiento de dos radiobuttons ya que justamente puedes desmarcar ambos. Quizá sólo sea una razón estética.

// Saludos

:rolleyes: Parece que estamos exigentes, pero si es una razón estética ya no digo mas. Mi confusión se debió a que no entendía porque alguien querría agregar código solo para que un control se comportara como otro, pero si los radiobutton os parecen feos adelante.

roman 24-08-2006 03:29:45

Bueno, es que yo no sé si es una cuestión estética. Es sólo que en el código que él intentó, explícitamente pone en true el checkbox que llama. Por eso supuse que no quería dejar que se desmarcara.

Ahora, tratando de encontrar un código compacto como el de seoane, lo más que me acerco es a esto:

Código Delphi [-]
{$writeableconst on}
procedure TForm1.CheckBoxClick(Sender: TObject);
const
  Checando: Boolean = false;

begin
  if Checando then exit;

  Checando := true;
  if Sender = CheckBox1
    then CheckBox2.Checked := false
    else CheckBox1.Checked := false;

  TCheckBox(Sender).Checked := true;
  Checando := false;
end;
{$writeableconst off}

usando un sólo evento para ambos.

// Saludos

vtdeleon 24-08-2006 04:33:29

Si hablamos de hacerlo chiquito o compacto :D:D
Código Delphi [-]
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  if TCheckBox(Sender).Name = CheckBox1.Name then
    CheckBox2.Checked:= not TCheckBox(sender).Checked
  else
    CheckBox1.Checked:= not TCheckBox(sender).Checked;
end;
Saludos

roman 24-08-2006 05:51:10

Pero así tiene un efecto extraño: cuando haces click sobre el que está marcado, la marca pasa al otro.

// Saludos

vtdeleon 24-08-2006 06:35:57

Saludos
Cita:

Empezado por roman
Pero así tiene un efecto extraño: cuando haces click sobre el que está marcado, la marca pasa al otro.

Creí que queria un comportamiento similar al Radiobutton
Cita:

Empezado por TriLoCBA
Necesito simular el efecto de seleccion unica que poseen los radiobutton con un par de checkbox

Ya no entiendo:confused:

vtdeleon 24-08-2006 06:43:43

Ooh ya, se me ha chispoteado el asunto, tienes razón roman

roman 24-08-2006 06:49:05

El punto es que cuando se cambia la propiedad checked por código, se genera un evento OnClick y una recursividad que da al traste con el stack. Por ello es que no he visto forma de hacerlo como no sea controlando de una u otra manera cuando se está dentro del evento.

// Saludos

Lepe 24-08-2006 11:05:53

En su momento tambien me desconcertó ese funcionamiento, así que derivé de Tcheckbox y me creé el mio propio:
Código Delphi [-]

unit CheckBoxNoClick;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls;

type
  TCheckBoxNoClick = class(tcheckBox)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    procedure SetChecked(Value:Boolean);
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TCheckBoxNoClick]);
end;

{ TCheckBoxNoClick }

procedure TCheckBoxNoClick.SetChecked(Value: Boolean);
begin
  try
    clicksdisabled := True;
    inherited;
  finally
    ClicksDisabled:= False;
  end;
end;

end.

Cuando no se quiere que desencadene el evento OnClick por código, se usa SetChecked.
Cuando se necesita el comportamiento normal, se usa como siempre.

Saludos

ContraVeneno 24-08-2006 15:39:18

Muy buenas respuestas... pero sigue faltando una que no entiendo, y que el único que puede responder es el autor de este hilo:

¿porqué no quieres usar RadioButtons?

TriLoCBA 25-08-2006 00:34:18

Muchas gracias a todos por vuestras rapidas respuestas...!!!

Me pone orgulloso que un tema tan modesto haya juntado a los grandes del foro !!!:D

Para despejar dudas, la utilizacion de los checkbox en lugar de radiobutton responde a dos situaciones:

1ra. Forman parte de un form que tiene como fondo una imagen especifica sobre la cual no puedo poner ningun componente como el Tpanel ó el TRadioGroup que no traiga la propiedad Transparent; y en el mismo formulario ya poseeo una serie de RadioButtons para otra función.

y 2da., aunque menos importante, me agradan visualmente mas los checkboxs sobre los radiobuttons.

Probare los ejemplos enviados, y de nuevo muchas gracias.

Un abrazo.

vtdeleon 25-08-2006 00:52:01

Cita:

Empezado por Lepe
Cuando no se quiere que desencadene el evento OnClick por código, se usa SetChecked.
Cuando se necesita el comportamiento normal, se usa como siempre.

No me ha funcionado :confused:. Algo se me escapa

Saludos

Lepe 25-08-2006 09:26:29

En qué delphi lo has probado vtdeleon?

En Delphi 6 Enterprise lo he usado con éxito.

Como ves los de Borland ya pensaron en ello y precisamente por eso tienen una variabla protected/private (no recuerdo) llamada ClickDisabled.

Ahora mismo en Delphi 6 no puedo mirarlo. En BDS2006 la cosa ha cambiado:
Código Delphi [-]
procedure TCustomCheckBox.SetState(Value: TCheckBoxState);
begin
  if FState <> Value then
  begin
    FState := Value;
    if HandleAllocated then
      SendMessage(Handle, BM_SETCHECK, Integer(FState), 0);
    if not ClicksDisabled then Click; <-------------------------
  end;
end;
Ahora es el procedimiento SetState.

Saludos

vtdeleon 25-08-2006 14:31:22

Cita:

Empezado por Lepe
Ahora mismo en Delphi 6 no puedo mirarlo. En BDS2006 la cosa ha cambiado:

Por ahí andaban los tiros.

Ahora no lo puedo probar, no tengo el delphi a mano.
Saludos

TriLoCBA 27-08-2006 00:25:30

Perfecto... El primer codigo que planteo Roman es lo que necesitaba !!!:)

Muchas gracias a todos por la ayuda...

Un abrazo.

TriloCba


La franja horaria es GMT +2. Ahora son las 21:05:12.

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