列表框 onchange 事件,组件
Listbox Onchange Event, component
我想做一个基于TListBox
的组件。
当Items.Count
改变时,我想更新TLabel
的Caption
:
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.
TListBox
从 TControl
继承了一个受保护的 Changed()
方法,它向派生的 类 发送 CM_CHANGED
消息。 TListBox
调用 Changed()
回复 LBN_SELCHANGE
。您不需要定义自己的 Change()
方法,只需处理 CM_CHANGED
即可。
TListBox.SetItemIndex()
向列表框 HWND
发送 LB_SETCURSEL
消息。该消息不会触发 LBN_SELCHANGE
,因此您必须自己检测 ItemIndex
更改。你试图做的。
但是,这些问题仅适用于选择更改,不适用于Item.Count
更改。更改 ItemIndex
不会更改 Items.Count
。如果您的目标只是在列表框中添加或删除项目时显示新的 Items.Count
,则需要处理 LB_ADDSTRING
、LB_INSERTSTRING
、LB_DELETESTRING
和 LB_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;
我想做一个基于TListBox
的组件。
当Items.Count
改变时,我想更新TLabel
的Caption
:
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.
TListBox
从 TControl
继承了一个受保护的 Changed()
方法,它向派生的 类 发送 CM_CHANGED
消息。 TListBox
调用 Changed()
回复 LBN_SELCHANGE
。您不需要定义自己的 Change()
方法,只需处理 CM_CHANGED
即可。
TListBox.SetItemIndex()
向列表框 HWND
发送 LB_SETCURSEL
消息。该消息不会触发 LBN_SELCHANGE
,因此您必须自己检测 ItemIndex
更改。你试图做的。
但是,这些问题仅适用于选择更改,不适用于Item.Count
更改。更改 ItemIndex
不会更改 Items.Count
。如果您的目标只是在列表框中添加或删除项目时显示新的 Items.Count
,则需要处理 LB_ADDSTRING
、LB_INSERTSTRING
、LB_DELETESTRING
和 LB_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;