いつも参考にしています。
TListViewのチェックボックスクリック時に1つだけ選択する方法を探しています。
現在ListViewのClickイベントでListItem選択した時に1つだけ選択する方法はできたのですが,
チェックボックスをクリックした時に対応していません。
※異なるチェックボックスを選択しても,ListViewは前回のListItemを選択したまま
対処する為のListViewのChangeイベント内にてListItemを選択する処理を加えてみたのですが,
無限ループ(スタックオーバーフロー)が発生してしまいます。
チェックボックス機能を無効にすれば今回の件は考えなくていいのですが(MultiSelect機能で制御可能な為),
有効にした状態で処理する方法を考えています。
どなたか良い案お持ちの方がいればよろしくお願いします。
環境:Delphi7
//リストビュー クリック時
procedure TForm1.ListView1Click(Sender: TObject);
begin
ListItemSelect;
end;
//リストアイテム選択
procedure TForm1.ListItemSelect;
var
i: Integer;
TmpItem: TListItem;
begin
if Assigned(ListView1.Selected) = False then Abort;
TmpItem := ListView1.Selected;
for i := 0 to ListView1.Items.Count - 1 do
begin
if TmpItem = ListView1.Items.Item[i] then
begin
ListView1.Items.Item[i].Checked := True;
end
else
begin
ListView1.Items.Item[i].Checked := False;
end;
end;
end;
//チェックボックス変更時
procedure TForm1.ListView1Change(Sender: TObject;
Item: TListItem; Change: TItemChange);
var
IsChecked: Boolean;
begin
if Change = ctState then
begin
IsChecked := Item.Checked;
if (Item.StateIndex = 1) <> IsChecked then
begin
Item.Selected := True; ※無限ループする原因
ListItemSelect;
end;
end;
end;
ListItem選択時にも、チェックをONにするんだよね?(RowSelectはTrue)
var
si: TlistItem = nil;
procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Item: TlistItem;
begin
with TListView(Sender) do begin
Item := GetItemAt(X, Y);
if Item <> nil then begin
Selected := Item;
Selected.Checked := True;
ItemFocused := Item;
if (si <> nil)and(si <> Item) then si.Checked := False;
si := Item;
end;
end;
end;
↓↑キーにも対応しなくちゃネ。
procedure TForm1.ListView1Change(Sender: TObject; Item: TListItem; Change: TItemChange);
begin
with TListView(Sender) do begin
if Selected = nil then exit;
Selected.Checked := True;
if (si <> nil)and(si <> Item) then si.Checked := False;
si := Item;
end;
end;
返信ありがとうございます。
おかげさまで思っていた動作になりました。
また↑↓での制御は諦めていたのですで非常に助かりました。
別ルーチンでChangeイベントの制御とぶつかったのですが,
そこはソース見直すことでうまくいきました。
また何かあったときはよろしくお願いします。ありがとうございました。
ツイート | ![]() |