wqclatre
asked on
TListView and checkboxes
How can I trap when a checkbox get checked and unchecked (an checkbox inside a listview. IE Checkboxses = True on TListView)
How can I set the state to clGreyed on a checkbox inside a TListView
How can I set the state to clGreyed on a checkbox inside a TListView
In fact it will work if you dont have rowselect on.
My mistake.
My mistake.
>How can I set the state to clGreyed on a checkbox inside a TListView<
Sorry this part Im not sure if you can.
Sorry this part Im not sure if you can.
ASKER
Strange. I thought I made a comment here before.
Your "solution" don't solve my problem since I don't know the state before. I can't know if just an item is cliked at or if the chekbox is checked. The strange thing is that VB have an OnItemChecked event. Delphi don't.
Your "solution" don't solve my problem since I don't know the state before. I can't know if just an item is cliked at or if the chekbox is checked. The strange thing is that VB have an OnItemChecked event. Delphi don't.
well you can code it manually
here is an example i wrote for you on how to notice the "Checkbox change" if the viewstyle is vsReport
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
// some constants for dealing with the checkbox position - only for ViewStyle vsReport atm
const
lv_distancefromleft = 3;
lv_distancefromtop = 18;
lv_checkboxheight = 18;
lv_checkboxwidth = 15;
type
TForm1 = class(TForm)
ListView1: TListView;
Memo1: TMemo;
procedure ListView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
// ADDED EVENT HERE FOR HANDLING CHECKBOX CHANGE NICELY
procedure OnListviewItemChecked(Send er: TObject; const Item: TListItem; const NewState: boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.ListView1MouseDown( Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
CurrentlyPressedListViewCh eckbox: integer;
begin
if
( X >= lv_distancefromleft) and
(X < (lv_distancefromleft + lv_checkboxwidth)) and
(Y >= lv_distancefromtop) and
(Y < lv_distancefromtop + ( lv_checkboxheight * (Sender as TListView).Items.Count) )
then
begin
CurrentlyPressedListViewCh eckbox := Trunc( (Y - lv_distancefromtop) / lv_checkboxheight);
// now call our nice handling routine
OnListviewItemChecked( Sender, (Sender as TListView).Items[Currently PressedLis tViewCheck box],
(Sender as TListView).Items[Currently PressedLis tViewCheck box].Check ed);
end;
end;
// This procedure is just an example f you wanted to have 1 nice routine for handling the "checkbox"
procedure TForm1.OnListviewItemCheck ed(Sender: TObject; const Item: TListItem; const NewState: boolean);
begin
if NewState then memo1.lines.add('checked item: ' + inttostr(Item.index))
else memo1.lines.add('unchecked item: ' + inttostr(Item.index))
// old check state is obviously "not item.checked"
end;
end.
here is an example i wrote for you on how to notice the "Checkbox change" if the viewstyle is vsReport
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
// some constants for dealing with the checkbox position - only for ViewStyle vsReport atm
const
lv_distancefromleft = 3;
lv_distancefromtop = 18;
lv_checkboxheight = 18;
lv_checkboxwidth = 15;
type
TForm1 = class(TForm)
ListView1: TListView;
Memo1: TMemo;
procedure ListView1MouseDown(Sender:
// ADDED EVENT HERE FOR HANDLING CHECKBOX CHANGE NICELY
procedure OnListviewItemChecked(Send
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.ListView1MouseDown(
Shift: TShiftState; X, Y: Integer);
var
CurrentlyPressedListViewCh
begin
if
( X >= lv_distancefromleft) and
(X < (lv_distancefromleft + lv_checkboxwidth)) and
(Y >= lv_distancefromtop) and
(Y < lv_distancefromtop + ( lv_checkboxheight * (Sender as TListView).Items.Count) )
then
begin
CurrentlyPressedListViewCh
// now call our nice handling routine
OnListviewItemChecked( Sender, (Sender as TListView).Items[Currently
(Sender as TListView).Items[Currently
end;
end;
// This procedure is just an example f you wanted to have 1 nice routine for handling the "checkbox"
procedure TForm1.OnListviewItemCheck
begin
if NewState then memo1.lines.add('checked item: ' + inttostr(Item.index))
else memo1.lines.add('unchecked
// old check state is obviously "not item.checked"
end;
end.
That does the same as what I wrote before
Im not sure why you want to know the state before, it can only be one of two, so if it is checked now, it must have been unchecked.
If you REALLY wanted to hold values for some other reason, maybe store them in an array for checking later
type
TForm1 = class(TForm)
ListView1: TListView;
Memo1: TMemo;
procedure ListView1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
arrChecked: array of Boolean;
public
{ Public declarations }
end;
var
Form1: TForm;
implementation
{$R *.dfm}
procedure TForm1.ListView1Click(Send er: TObject);
var
ListItem:TListItem;
CurrPos:TPoint;
i: Integer;
begin
CurrPos:=Mouse.CursorPos;
CurrPos:=ListView1.ScreenT oClient(Cu rrPos);
ListItem:=ListView1.GetIte mAt(CurrPo s.x,CurrPo s.y);
if Assigned(ListItem) then
begin
// this bit is pretty pointless to be honest
// it can only be one of two states
i := ListItem.Index;
if arrChecked[i] then
Memo1.Lines.Add('Item ' + IntToStr(i) + ' was previously Checked')
else
Memo1.Lines.Add('Item ' + IntToStr(i) + ' was previously unchecked');
if ListItem.Checked then
Memo1.Lines.Add('Item ' + IntToStr(i) + ' is now Checked')
else
Memo1.Lines.Add('Item ' + IntToStr(i) + ' is now unchecked');
// set the item
arrChecked[i] := ListItem.Checked;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
var
i: Integer;
begin
// get current states
SetLength(arrChecked, ListView1.Items.Count);
for i := 0 to Pred(ListView1.Items.Count ) do
arrChecked[i] := ListView1.Items[i].Checked ;
end;
Im not sure why you want to know the state before, it can only be one of two, so if it is checked now, it must have been unchecked.
If you REALLY wanted to hold values for some other reason, maybe store them in an array for checking later
type
TForm1 = class(TForm)
ListView1: TListView;
Memo1: TMemo;
procedure ListView1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
arrChecked: array of Boolean;
public
{ Public declarations }
end;
var
Form1: TForm;
implementation
{$R *.dfm}
procedure TForm1.ListView1Click(Send
var
ListItem:TListItem;
CurrPos:TPoint;
i: Integer;
begin
CurrPos:=Mouse.CursorPos;
CurrPos:=ListView1.ScreenT
ListItem:=ListView1.GetIte
if Assigned(ListItem) then
begin
// this bit is pretty pointless to be honest
// it can only be one of two states
i := ListItem.Index;
if arrChecked[i] then
Memo1.Lines.Add('Item ' + IntToStr(i) + ' was previously Checked')
else
Memo1.Lines.Add('Item ' + IntToStr(i) + ' was previously unchecked');
if ListItem.Checked then
Memo1.Lines.Add('Item ' + IntToStr(i) + ' is now Checked')
else
Memo1.Lines.Add('Item ' + IntToStr(i) + ' is now unchecked');
// set the item
arrChecked[i] := ListItem.Checked;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
var
i: Integer;
begin
// get current states
SetLength(arrChecked, ListView1.Items.Count);
for i := 0 to Pred(ListView1.Items.Count
arrChecked[i] := ListView1.Items[i].Checked
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Im presuming that you are populating a lot of data rather than one column, otherwise you could use a CheckListBox which has an OnClickCheck event.
procedure TForm1.ListView1Click(Send
var
ListItem:TListItem;
CurrPos:TPoint;
begin
CurrPos:=Mouse.CursorPos;
CurrPos:=ListView1.ScreenT
ListItem:=ListView1.GetIte
if Assigned(ListItem) then
begin
if ListItem.Checked then ShowMessage(ListItem.Capti
else ShowMessage(ListItem.Capti
end;
end;
Just make sure you have rowselect = True