Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

TElXTree: Click on an Item's Checked RadioButton: Uncheck it - how?

I am using the radiobutton as a selector for a task, but if the user clicks on the checked radio button it is meant to toggle it off.

It seems that because OnItemChecked is called after OnMouseUp, there is no way for me to UnCheck a checked radio-button by the user clicking on the radio-button. Is there a way?

I have declared a variable (DoUncheckItem : Boolean) that is set to True in OnMouseDown when a checked radiobutton is clicked on, and then in onItemChecked I check if the variable DoUncheckItem is True, and if so, I uncheck the item after it is checked.

This works fine if there is a delay of about 1 second between clicking on the active radiobutton.

This causes problems when clicking on the same radiobutton twice in quick succession.

What is a better way of doing this?

Here is the essential code:

procedure TMainForm.ItemTreeMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Item      : TElXTreeItem;
  ItemPart  : TSTXItemPart;
  HitColumn : Integer;
begin
  DoUnCheckRadioItem := False;

  with ItemTree do
  begin
    Item := GetItemAt(X, Y, ItemPart, HitColumn);

    ItemPartSaved  := ItemPart;
    HitColumnSaved := HitColumn;

    case ItemPart of

      ipCheckBox:
      begin
        DoUnCheckRadioItem := Item.Checked;

        Item.Checked := not Item.Checked;
      end;

    end; {case}
  end;
end;

procedure TMainForm.ItemTreeItemChecked(Sender: TObject; Item: TElXTreeItem);
begin
  if DoUnCheckRadioItem then
  begin
    Item.Checked := False;
  end;

  if Item.Checked then
  begin
    if PreviousItem <> nil then
    begin
      // Process Previous Item

      PreviousItem.Checked := False;
    end;

    // Process newly-selected item
  end
  else // not checked
  begin
    // Process newly-selected item
  end;

  with ItemTree do
  begin
    if PreviousItem = Item then
    begin
      PreviousItem := nil;
    end
    else
    begin
      PreviousItem := Item;
    end;
  end;
end;

This is a convoluted way to ensure that a checked radiobutton is made to be unchecked if clicked on.

In the OnChecked event the status of the item is always Checked whether begun unchecked or checked, so is of no use.

Please see my request title "TElXTree: OnCheckBoxChanging(...)".
Such an event would enable this requirement and another to be solved easily.

Regards,
Raymond

Comments

  • 4 Comments sorted by Votes Date Added
  • Sorry, but I trimmed one line too many from the last part of the code.
    The focused item is also updated.

        with ItemTree do
        begin
          ItemFocused := Item;

          if PreviousItem = Item then
          begin
            PreviousItem := nil;
          end
          else
          begin
            PreviousItem := Item;
          end;
        end;

    Raymond
  • After investigating a little about radiobuttons, I've decided that allowing the user to uncheck a radiobutton by clicking on it goes against Windows principles and would confuse the user, who doesn't see this behaviour anywhere else.

    I have used a work-around for this problem.

    I use checkboxes all the time. 

    They look like check-boxes when my app is in multi-select mode and look like radio-buttons when in single-select mode.

    In single-select mode I manage the deselection of the current item when the user clicks on the radio-button of another item.

    Raymond
  • Thank you for feedback.
Sign In or Register to comment.