复选框不在TListView组件中滚动

时间:2011-04-24 16:04:17

标签: delphi listview delphi-xe

我已经创建了ListView并添加了复选框,以便在需要时检查每一行。一切都很好,直到列表视图中有很多项目,所以它需要scolling。我在线查看,然后我看到如果滚动滚动条,复选框不会滚动其他内容。

我的代码:

unit ShareCommissionDialog;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, sButton, ComCtrls, sListView, sCheckBox, DataManager;

type
  TdlgShareCommission = class(TForm)
    lvEmployees: TsListView;
    btnCancel: TsButton;
    btnDone: TsButton;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure btnDoneClick(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);

  private
    manager: TDataManager;
    ListViewCheckBoxList: TList;
    employeeIDs: TStringList;

    procedure ListViewCheckBoxCreate(List: TsListView; employeeID: string; R: TRect);
    procedure ListViewCheckBoxClick(Sender: TObject);
    procedure ListViewCheckBoxSelected(item: Integer; List: TsListView);
    procedure ListViewCheckBoxUnselected(item: Integer; List: TsListView);

    procedure PopulateEmployees;
    procedure ShowSelectedEmployees;
    procedure MarkRows;

  public
    property DataManager: TDataManager read manager write manager;
    property CommissionReceivers: TStringList read employeeIDs write employeeIDs;

  end;

var
  dlgShareCommission: TdlgShareCommission;

implementation

{$R *.dfm}

procedure TdlgShareCommission.btnCancelClick(Sender: TObject);
begin
  employeeIDs := employeeIDs;
end;

procedure TdlgShareCommission.btnDoneClick(Sender: TObject);
var
  i, j: Integer;

begin
  employeeIDs := TStringList.Create;

  for i := 0 to ListViewCheckBoxList.Count - 1 do
  begin
    if TsCheckBox(ListViewCheckBoxList[i]).Checked then
    begin
      for j := 0 to manager.Data.Employees.Count - 1 do
      begin
        if TsCheckBox(ListViewCheckBoxList[i]).Tag = StrToInt(manager.Data.Employees[j].ID) then
        begin
          employeeIDs.Add(manager.Data.Employees[j].ID);
          Break;
        end;
      end;
    end;
  end;
end;

procedure TdlgShareCommission.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  manager.GetEmployees(manager.Data.SelectedPOS.ID);
end;

procedure TdlgShareCommission.FormCreate(Sender: TObject);
begin
  ListViewCheckBoxList := TList.Create;
end;

procedure TdlgShareCommission.ListViewCheckBoxCreate(List: TsListView; employeeID: string; R: TRect);
function NewViewCheckBox: TsCheckBox;
  begin
    Result := TsCheckBox.Create(Self);
    Result.Tag := StrToInt(employeeID);
    Result.Parent := List;
    Result.BoundsRect := R;
    Result.Checked := False;

    Result.OnClick := ListViewCheckBoxClick;
  end;
begin
  ListViewCheckBoxList.Add(NewViewCheckBox);
end;

procedure TdlgShareCommission.FormShow(Sender: TObject);
begin
  if employeeIDs <> nil then
  begin
    PopulateEmployees;
    ShowSelectedEmployees;
    MarkRows;
  end
  else
  begin
    PopulateEmployees;
    MarkRows;
  end;

  //PopulateEmployees;
  //MarkRows;
end;

procedure TdlgShareCommission.ListViewCheckBoxClick(Sender: TObject);
var
  i: Integer;

begin
  for i := 0 to ListViewCheckBoxList.Count - 1 do
  begin
    if (i+1) <= (ListViewCheckBoxList.Count - 1) then
      if not TsCheckBox(ListViewCheckBoxList[i+1]).Enabled then
      begin
        TsCheckBox(ListViewCheckBoxList[i+1]).Checked := TsCheckBox(ListViewCheckBoxList[i]).Checked;
      end;
  end;

  MarkRows;
end;

procedure TdlgShareCommission.MarkRows;
var
  j: Integer;

begin
  for j := 0 to lvEmployees.Items.Count - 1 do
  begin
    if not TsCheckBox(ListViewCheckBoxList[j]).Checked then
    begin
      ListViewCheckBoxSelected(j, lvEmployees);
    end
    else
    begin
      ListViewCheckBoxUnselected(j, lvEmployees);
    end;
  end;
end;

procedure TdlgShareCommission.ListViewCheckBoxSelected(item: Integer; List: TsListView);
begin
  with List do
  begin
    Items[item].Selected := False;
  end;
end;

procedure TdlgShareCommission.ListViewCheckBoxUnselected(item: Integer; List: TsListView);
begin
  with List do
  begin
    Items[item].Selected := False;
  end;
end;

procedure TdlgShareCommission.PopulateEmployees;
var
  i: Integer;
  R: TRect;
  employeeRow: TListItem;

begin
  with lvEmployees do
  try
    Items.BeginUpdate;
    Items.Clear;

    manager.GetEmployees(manager.Data.SelectedPOS.ID);

    for i := 0 to manager.Data.Employees.Count - 1 do
    begin
      employeeRow := Items.Add;

      R := Items[i].DisplayRect(drBounds);
      R.Left := 5;
      R.Top := R.Top + 1;
      ListViewCheckBoxCreate(lvEmployees, manager.Data.Employees[i].ID, R);
      Items[i].Data := TsCheckBox(ListViewCheckBoxList[i]);

      employeeRow.SubItems.Add(manager.Data.Employees[i].FirstName + ' ' + manager.Data.Employees[i].LastName);
    end;
  finally
    lvEmployees.Items.EndUpdate;
  end;
end;

procedure TdlgShareCommission.ShowSelectedEmployees;
var
  i, j: Integer;

begin
  for j := 0 to lvEmployees.Items.Count - 1 do
  begin
    for i := 0 to employeeIDs.Count - 1 do
    begin
      if TsCheckBox(ListViewCheckBoxList[j]).Tag = StrToInt(employeeIDs[i]) then
      begin
        TsCheckBox(ListViewCheckBoxList[j]).Checked := True;
      end;
    end;
  end;
end;
end.

我需要在代码中添加哪些复选框也会与其他内容一起滚动?

1 个答案:

答案 0 :(得分:6)

标准 ListView有一个名为checkboxes的属性,可以设置为true。
如果您使用它,那么您不必乱用自己的复选框 我在这个控件中没有正确显示复选框时从未遇到任何问题。

此属性在ViewStyle:= vsListViewStyle:= vsReport

中效果最佳

或者,如果您想要某些项目的复选框,而不是其他项目的复选框 然后制作一个复选框的图片(1个未选中,1个已选中)并将它们添加到ImageList中 如果项目需要复选框,请将其ImageIndex属性设置为未选中项目的属性。如果需要检查,请将其ImageIndex属性设置为选中的图像 这适用于ViewStyle:= vsReportViewStyle:= vsList

您正在使用自定义ListView TsListView控件,请尝试使用标准ListView,看看是否出现奇怪的行为。