- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要根据是否在列表中至少选择一行来启用或禁用按钮。
下面是重现此问题的代码。该列表是使用 OnData 事件填充的,并且允许选择多行。
我认为我可以使用 OnSelectItem 来检测用户何时更改选择,然后使用 TListView SelCount 函数来检测所选行的数量。
问题是当用户选择多行时 SelCount 返回 0。如果列表是手动填充的(即不通过 OnData 事件),则此方法可以正常工作。
有什么想法吗?
谢谢
更新:使用 OnChange 事件似乎可以解决问题。不过,理解为什么当选择多行时(从 SelectItem 事件中)SelCount 返回 0 仍然会很有趣。
另一个更新:我发布了一个测试项目:https://dl.dropboxusercontent.com/u/35370420/TestListView2.zip以及屏幕截图:
要重现此问题,请运行应用程序,选择 Item1,然后按住 SHIFT 键并单击 Item2。该按钮被禁用。我的目的是只要列表中至少选择了一项,就动态启用该按钮。如果没有选定的项目,该按钮将被禁用。
PAS 文件:
unit MainUnit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls;
type
TForm3 = class(TForm)
ListView1: TListView;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure ListView1Data(Sender: TObject; Item: TListItem);
procedure ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.FormCreate(Sender: TObject);
begin
ListView1.Items.Count := 5;
end;
procedure TForm3.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := String.Format('Item%d', [Item.Index]);
end;
procedure TForm3.ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
begin
Button1.Enabled := ListView1.SelCount > 0;
OutputDebugString(pchar(String.Format('SelCount = %d', [ListView1.SelCount])));
end;
end.
表格:
object Form3: TForm3
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 600
ClientWidth = 952
Color = clBtnFace
DoubleBuffered = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object ListView1: TListView
Left = 168
Top = 160
Width = 250
Height = 150
Columns = <
item
AutoSize = True
Caption = 'Test'
end>
HideSelection = False
MultiSelect = True
OwnerData = True
TabOrder = 0
ViewStyle = vsReport
OnData = ListView1Data
OnSelectItem = ListView1SelectItem
end
object Button1: TButton
Left = 168
Top = 120
Width = 75
Height = 25
Caption = 'Some Action'
Enabled = False
TabOrder = 1
end
end
最佳答案
根本问题是,当您 SHIFT+Click 多个项目时,您将不会获得已选择项目的任何 OnSelectItem
事件。 SHIFT+Click 会首先取消选择所有 ListView 项,从而触发带有 Item=nil
和 Selected= 的单个
,在新项目被选中之前。在该事件发生时,OnSelectItem
事件FalseTListView.SelCount
实际上为 0,因此您禁用了按钮,但随后没有进一步的 OnSelectItem
事件来告诉您新项目已被添加。已选中,因此您无需再次检查 SelCount
来重新启用该按钮。
OnSelectItem
事件被触发以回复 LVN_ITEMCHANGED
当单个项目在选定和未选定之间更改状态时,或者当整个 ListView 中的所有项目更改为相同的选定/未选定状态时发出通知。但是,在虚拟模式下,当多个连续项目同时更改为相同状态时,Windows 可以改为发送单个 LVN_ODSTATECHANGED
该范围的项目的通知。 TListLiew
在接收到LVN_ODSTATECHANGED
时不会触发OnSelectItem
,而是触发OnDataStateChange
,例如:
procedure TForm3.ListView1DataStateChange(Sender: TObject; StartIndex, EndIndex: Integer; OldState, NewState: TItemStates);
begin
if (NewState * [isSelected]) <> (OldState * [isSelected]) then
Button1.Enabled := ListView1.SelCount > 0;
end;
因此,您需要同时使用 OnSelectItem
和 OnDataStateChange
来处理所有可能的选择/取消选择状态更改。
最好的解决方案是不要在单个项目状态更改时手动启用/禁用 TButton
。在表单上放置一个 TActionManager
,创建一个新的 TAction
并将其分配给 TButton.Action
属性,然后使用 TAction .OnUpdate
事件根据当前TListView.SelCount
启用/禁用TAction
,例如:
procedure TForm3.MyActionUpdate(Sender: TObject);
begin
MyAction.Enabled := ListView1.SelCount > 0;
end;
每当主消息队列空闲时,包括在处理 ListView 通知消息之后,都会自动启用/禁用关联的 TButton
。这样,无论使用哪种输入组合来选择/取消选择 ListView 项目,您都可以保持 TButton
更新。
关于delphi - TListView SelCount 报告虚拟列表中的项目数错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22240431/
有WHERE 1=1有什么作用如果您在脚本(伪代码)中编写此请求: sql = "SELECT f1,f2,f3 FROM t WHERE 1=1" ++ restOfTheClause
这个问题已经有答案了: R: Convert delimited string into variables (3 个回答) 已关闭 5 年前。 我有一个包含电影数据的表,在最后一列中,它包含电影所属
假设我有一个基类: struct A{ virtual void foo() = 0; }; 然后假设我有一个这样的派生类: struct B : public virtual A{ voi
我有一个小问题,我的 << 运算符没有被正确调用。 这是我的: class SomeInterface { friend std::ostream& operator<<(std::ostrea
首先,我来自 Java 社区,并且仍然是 C++ 的学习者。 请看下面的类 第二张图片显示了类“GameObject”的子类。它还有一个 Display() 方法。 GameObject类有5个子类,
我这里遇到了一些问题。我试图让我的代码像 java 中的接口(interface)一样工作。这个类被其他 2 个继承,因为它们导致了一些问题。而且我还想知道我是否做对了,以及改进我的代码的方法。我是新
在 C++ 中,我有一个基类 A,一个子类 B。两者都有虚方法 Visit。我想在 B 中重新定义“访问”,但 B 需要访问每个 A(以及所有子类)的“访问”功能。 我有类似的东西,但它告诉我 B 无
我有一个抽象类,它是类层次结构的根。该根类有一个带有一些简单实现的方法,似乎没有必要随时随地更改该实现。 使该方法成为非虚方法很好,但是某些子类可能会意外地重新实现它。在这种情况下,虚拟 final方
在 MSDN 上,我发现在抽象方法声明中使用“virtual”修饰符是错误的。我的一位同事应该是非常有经验的开发人员,但他在他的代码中使用了这个: public abstract class Busi
C++ 虚函数表是仅用于确定调用虚函数时应该执行哪一段代码,还是在运行时有其他用途? 在维基百科上,它列出了“动态调度”作为一个原因,但没有深入了解 C++ 的更多细节...... 最佳答案 一些实现
页面大小是否恒定?更具体地说,getconf PAGE_SIZE 给出 4096,这很公平。但这可以通过程序的运行时间改变吗?或者它在整个操作系统进程生成过程中是否保持不变。 IE。 , 进程是否可能
析构函数(当然还有构造函数)和其他成员函数之间的区别在于,如果常规成员函数在派生类中具有主体,则仅执行派生类中的版本。而在析构函数的情况下,派生版本和基类版本都会被执行? 很高兴知道在析构函数(可能是
如果一个函数被定义为虚函数并且与纯虚函数相同,这究竟意味着什么? 最佳答案 来自 Wikipedia's Virtual function... In object-oriented programm
我有一个在 Jetty 下运行的应用程序,我希望该应用程序返回自引用绝对 URL(生成 RSS 提要时,因此客户端必须能够在没有“当前 URL”上下文的情况下工作)。 问题是我事先不知道应用程序将部署
如何在两个virtualtreeview之间复制以复制所有列,而不仅仅是第一列? 复制前: 复制后: 最佳答案 树控件不保存任何数据。它不包含要显示的列数据,因此无法复制它。而是,当树控件想要显示任何
我已将 ShowHint 设置为 true 并将 HintMode 设置为 hmToolTip,但是当我将光标悬停在控件上时,我的 OnGetHint() 事件处理程序甚至没有断点。 知道我做错了什么
我的 friend 正在 Delphi 中使用 VirtualTreeView 工作,并且遇到了下一个问题:他有两列,第一列的每一行都有数据和子项。是否可以不更改第一列宽度来设置最大子列宽度? 图例:
我在我的 Virtual TreeView Component 中使用 TVirtualStringTree ( Delphi project 的一部分)我想创建一个 View ,其中 2 列可以有可
我想遍历 VirtualTreeView 的所有根并将其删除。 我不想清除它。 我收到此代码的访问冲突: var Node : PVirtualNode; begin if VirtualStri
我有一个可以输出表单的 PHP 文件。我想在服务器端调用这个 PHP 文件(当前使用“include”),填写并提交。 这样更好,因此我不必干预实际的 PHP 表单,只需处理表示层,以便数据可以被它自
我是一名优秀的程序员,十分优秀!