1

我想制作一个基于TListBox.

Items.Count更改时,我想更新Captiona TLabel

Label1.Caption := IntToStr(ListBox1.Items.Count);

我制作了下面的组件,但它不起作用:

unit UChangeListBox;

interface

uses
  Classes, StdCtrls, Messages;

type
  TChListBox = class(StdCtrls.TListBox)
  private
    FItemIndex: Integer;
    FOnChange: TNotifyEvent;
    procedure CNCommand(var AMessage: TWMCommand); message CN_COMMAND;
  protected
    procedure DoChange; virtual;
    procedure SetItemIndex(const Value: Integer); override;
  published
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
  end;

procedure Register;

implementation

procedure TChListBox.DoChange;
begin
  if Assigned(FOnChange) then
    FOnChange(Self);
end;

procedure TChListBox.CNCommand(var AMessage: TWMCommand);
begin
  inherited;
  if (AMessage.NotifyCode = LBN_SELCHANGE) and (FItemIndex <> ItemIndex) then
  begin
    FItemIndex := ItemIndex;
    DoChange;
  end;
end;

procedure TChListBox.SetItemIndex(const Value: Integer);
begin
  inherited;
  if FItemIndex <> ItemIndex then
  begin
    FItemIndex := Value;
    DoChange;
  end;
end;

procedure Register;
begin
  RegisterComponents('MyComponents',[TChListBox]);
end;

end.
4

1 回答 1

3

TListBox从 继承受保护的Changed()方法TControl,该方法将CM_CHANGED消息发送到派生类。 TListBox电话Changed()回复LBN_SELCHANGE。您不需要定义自己的Change()方法,只需处理即可CM_CHANGED

TListBox.SetItemIndex()LB_SETCURSEL向ListBox发送消息HWND。该消息不会触发LBN_SELCHANGE,因此您必须自己检测ItemIndex更改。你试图做的。

但是,这些问题仅适用于选择更改,不适用于Item.Count更改。改变ItemIndex不改变Items.Count。如果您的目标只是在从 ListBox 添加或删除项目时显示一个新项目,Items.Count则需要处理LB_ADDSTRINGLB_INSERTSTRING和消息。LB_DELETESTRINGLB_RESETCONTENT

尝试更多类似的东西:

type
  TChListBox = class(TListBox)
  private
    FOnItemCountChange: TNotifyEvent;
  protected
    procedure WndProc(var Message: TMessage); override;
  published
    property OnItemCountChange: TNotifyEvent read FOnItemCountChange write FOnItemCountChange;
  end;

procedure TChListBox.WndProc(var Message: TMessage);
var
  OldCount: Integer;
begin
  case Message.Msg of
    LB_ADDSTRING, LB_INSERTSTRING, LB_DELETESTRING:
    begin
      // for LB_(ADD|INSERT)STRING, Message.Result is the 0-based
      // index of the added string, or a LB_ERR... error code.
      //
      // for LB_DELETESTRING, Message.Result is the number of items
      // remaining in the list, or a LB_ERR... error code.
      //
      inherited;
      if (Message.Result >= 0) and Assigned(FOnItemCountChange) then
        FOnItemCountChange(Self);
    end;
    LB_RESETCONTENT:
    begin
      // the Message.Result is not used in this message.
      //
      OldCount := Items.Count;
      inherited;
      if (OldCount <> Items.Count) and Assigned(FOnItemCountChange) then
        FOnItemCountChange(Self);
    end;
  else
    inherited;
  end;
end;
于 2017-05-10T17:39:40.870 回答