【发布时间】:2012-06-05 18:51:29
【问题描述】:
[编译器:Delphi XE2]
昨天我花了一整天的时间尝试各种方法来完成这个特定的任务,但它们都以相同的结果结束。
使用 TRZCheckGroup 和此示例查看已检查的内容等..
procedure TFrmMain.cbOptionsChange(Sender: TObject; Index: Integer; NewState: TCheckBoxState);
var
ItmIndex0, ItmIndex1: Integer;
begin
{ Initialize ItemIndex's }
ItmIndex0 := -1;
ItmIndex1 := -1;
{ Return the position Index of the string's(0 and 1) }
ItmIndex0 := cbOptions.Items.IndexOf('One');
ItmIndex1 := cbOptions.Items.IndexOf('Two');
{ Which CheckBox has been Checked }
cbOptions.ItemChecked[ItmIndex0] := True;
cbOptions.ItemChecked[ItmIndex1] := False;
end;
注意:^这不是我的最终代码,只是我如何处理复选框的示例。
类似的东西 -
if cbOptions.ItemChecked[ItmIndex0] then
cbOptions.ItemChecked[ItmIndex1] := False
else cbOptions.ItemChecked[ItmIndex1] := True;
他们第一次工作,然后它总是评估为真,我明白为什么。只有当我取消选中第一个 CheckBox 时,else 位才会起作用,这显然不是我想要的结果。
似乎事件停止工作,并且在我的一些尝试中它由于某种原因被触发了两次。
cbListOptionsChange 上的 NewState 参数,这是什么,它可以帮助我吗?
对此的任何帮助将不胜感激。
谢谢。
if cbOptions.ItemChecked[ItmIndex0] then
cbOptions.ItemChecked[ItmIndex1] := False
else if cbOptions.ItemChecked[ItmIndex1] then
cbOptions.ItemChecked[ItmIndex0] := False;
如果第二个 CheckBox 被选中,那么我会检查第一个 CheckBox 是否按要求工作,但显然之后你不能再检查第二个 CheckBox。
Ken White - 片段(工作)。将组件的名称替换为 Default 否则人们可能会感到困惑,有时有助于默认命名以节省将来的问题。
procedure TForm1.RzCheckGroup1Change(Sender: TObject; Index: Integer; NewState: TCheckBoxState);
var
i: Integer;
begin
// Keep this event from being fired again while we're here.
// Your code isn't clear about what the actual name of the
// component or this event, (the event is named `cbListOptionsChange`,
// but your code references `cbOptions` - I don't know which is
// correct, so change it if needed in the next line and
// the one in the `finally` block below. I'm using `cbListOptions`
// here.
RzCheckGroup1.OnChange := nil;
try
// If we're getting notified of a new item being checked...
if NewState = cbChecked then
begin
// Iterate through the items, unchecking all that aren't
// at the index that just became checked.
// I wouldn't use `for..in`, because the ordering works better here
for i := 0 to RzCheckGroup1.Items.Count - 1 do
if i <> Index then
RzCheckGroup1.ItemChecked[i] := False; // Ryan - Just changed to this from this cbListOptions.Items[i].Checked := False;
end;
// Ryan - Uncomment these two lines if you want one of them to be Checked at all times, this will set the CheckBox you are trying to Uncheck to Checked.
//if not RzCheckGroup1.ItemChecked[Index] then
// RzCheckGroup1.ItemChecked[Index] := True;
finally
// Reconnect the event
RzCheckGroup1.OnChange := RzCheckGroup1Change;
end;
end;
【问题讨论】:
-
您选择了错误的控件。你所经历的挣扎是那个错误的结果。互斥选择的正确控制是单选组。
-
您还应该更加注意编译器警告。初始化 ItmIndex0 和 ItmIndex1 的代码是没有意义的,编译器会告诉你的。
-
是的,我知道 TRAdioGroup 最适合并给我我需要的结果,但我真的想使用 CheckBoxes。当我进行编译或构建时,我得到 0 个警告或提示,所以我不太确定你的意思:S
-
使用复选框会使您的用户感到困惑,但我想您知道这一点。 Q 中的代码会发出警告。从不使用分配给 ItmIndex0 的值。
-
在读取第一个值之前分配另一个值的事实就是出现警告的原因。也许您禁用了警告。事实上,这对你来说是一场斗争,这只是为你的 UI 罪行伸张正义!! ;-) 你可以让它工作。使用 Ken 的代码,但在修改 Checked 属性时禁用 OnChange 处理程序。我会在 OnChange 处理程序中使用重入保护。阻止导致堆栈溢出的重入执行的全局字段。
标签: delphi delphi-xe2 vcl