大事不好了!控件神经了!输出结果时好时坏!
本帖最后由 冥界3大法王 于 2024-3-10 21:56 编辑控件需要在此下载:https://www.alphaskins.com/dwnld.php不然没有sShellListView1这个控件哟~~
故事是这样的,我要加一个编辑框过滤文件的功能{:301_974:}
uses
IOUtils, Types;
procedure TMainForm.File_Filter_EditKeyPress(Sender: TObject; var Key: Char);
var
dir: TDirectory;
files: TStringDynArray;
str: string;
List: TListItem;====================================>后来单独加的
begin
sShellListView1.clear;
if Key = #13 then
begin
files := dir.GetFiles(数据路径);
for str in files do
begin
// showmessage(str); 文件全路径
// showmessage(ExtractFileName(str)); 只取文件名
if Pos(File_Filter_Edit.text, ExtractFileName(str)) > 0 then
begin
List.SubItems.Add(str);==============================>后来单独加的
// sShellListView1.AddItem(ExtractFileName(str), sShellListView1); //神经的代码在这句上,时而过滤输出结果是正确的
// Memo1.Lines.Add(str); 算法是对的!上一句有问题!Add加到Memo上没问题啊!!!
end;
ShowMessage(List.ToString);===========================>后来单独加的
// List.SubItems.Assign(sShellListView1.Items);=================>后来单独加的
end;
end;
end;
开始以为是因为
if Pos(File_Filter_Edit.text, ExtractFileName(str)) > 0 then 这句造成的,所以后来加了红字部分
因为确实会不严谨,所以后来加了为了局部匹配对比 本帖最后由 爱飞的猫 于 2024-3-11 01:54 编辑
因为你没有提供最小复现的项目代码,我也不懂 Delphi 的 IDE。
你文中提到的 AlphaSkins 是控件皮肤库,和 Delphi 本身没啥关系。本身应继承自 `TShellList` 控件。
---
网上晃悠了一圈,发现 Lazarus 使用的 Free Pascal 自带了这个 `TShellList` 控件而且不用额外配置,所以我就用它了。
(1) 第一种方法是利用 `FileUtil.FindAllFiles` 来进行过滤,但 Delphi 好像没这个东西:
```
procedure TForm1.BtnFilterClick(Sender: TObject);
var
i: Integer;
ListOfFiles: TStringList;
begin
ListOfFiles := TStringList.Create;
FileUtil.FindAllFiles(ListOfFiles, Dir_Input.Directory, Edit_Filter.Text, False, faAnyFile);
shellListView.Clear;
for i := 0 to ListOfFiles.Count - 1 do
begin
shellListView.AddItem(ExtractFileName(ListOfFiles), TStringWrapper.Create(ListOfFiles));
end;
end;
```
(2) 第二种方法则是用 `System.SysUtils` 中的 `FindFirst`/`FindNext`/`FindClose` 来查找信息:
```
procedure TForm1.BtnFilter2Click(Sender: TObject);
var
SearchRecord: TSearchRec;
FilePath: String;
begin
shellListView.Clear;
if FindFirst(Dir_Input.Directory + DirectorySeparator + Edit_Filter.Text, faAnyFile, SearchRecord) = 0 then
begin
repeat
if (SearchRecord.Attr and faDirectory) <> 0 then continue;
FilePath := Dir_Input.Directory + DirectorySeparator + SearchRecord.Name;
shellListView.AddItem(SearchRecord.Name, TStringWrapper.Create(FilePath));
until FindNext(SearchRecord) <> 0;
FindClose(SearchRecord);
end;
end;
```
实测效果如下:
![](https://imgsrc.baidu.com/forum/pic/item/4bed2e738bd4b31ca6910a81c1d6277f9e2ff85f.png)
完整项目代码(使用 Lazarus IDE 编译)和编译后的文件:(https://pan.baidu.com/s/12uHi8taR-tKTpZrXQXVzyg?pwd=wfcg)
@爱飞的猫
我去搜索这个控件名
搜索出来的东西外来安装的控件
如图所示,我觉得最有问题可能的就是最后一个参数。它说的是啥?对象。
如果输出结果到Memo1,则和预期结果一样。
我现在严重怀疑这个对象我的写法有问题。
明明上面POS函数对比的结果是对的。可是不对的结果为啥反而添加到了文件列表?可是为啥Memo1中添加来的却又是对的?
所以综合而看,我方认为最后一个参数对象,我写得有问题。改成啥呢?
https://static.52pojie.cn/static/image/hrline/2.gif
其实我也可以直接扔一个JamExplorerBrowser1控件,选项中开启显示文件路径、过滤栏即可。一行代码也不用写。
现在得到新结论:
我尝试把最后一个 对象参数修改为其他任意的控件名,都能调试通过。
但最终输出结果还是时对时不对。
所以,是不是 sShellListView1.AddItem 这个方法用的不对? 冥界3大法王 发表于 2024-3-11 10:02
现在得到新结论:
我尝试把最后一个 对象参数修改为其他任意的控件名,都能调试通过。
但最终输出结果还 ...
你应当参考库的文档。通常第二个参数的对象通常是与该项目相关联的数据,方便取 `.Selected.Data` 的时候用。
另外如果只是过滤到列表,你也可以考虑用回标准的 `TListView` 控件。 本帖最后由 冥界3大法王 于 2024-3-11 11:26 编辑
@爱飞的猫
我又换了个写法: 还是输出效果时而抽风。算了,扔个简单的实现控件就不纠结了,以后有时间再说。
感谢版主哥解答。
procedure TMainForm.File_Filter_EditKeyPress(Sender: TObject; var Key: Char);
var
dir: TDirectory;
files: TStringDynArray;
str: string;
ListItem: TListItem;
begin
sShellListView1.clear;
Memo1_BaoPo.Clear; //仅为测试
if Key = #13 then
begin
files := dir.GetFiles(数据路径);
for str in files do
begin
if Pos(File_Filter_Edit.text, ExtractFileName(str)) > 0 then
begin
//sShellListView1.AddItem(ExtractFileName(str), sShellListView1); //版本1写法时对时错
ListItem := sShellListView1.Items.Add;
ListItem.Caption := str; //版本2写法时对时错
Memo1_BaoPo.Lines.Add(str); //仅为测试
end;
end;
end;
end; 你的用法可能不对,VCL框架下TListView用法如下,你的那个控件可能继承自TListView,用法应该类似。
uses
Vcl.ComCtrls;
procedure TForm1.AddDataToListView;
var
ListItem: TListItem;
I: Integer;
begin
ListView1.Items.BeginUpdate;
try
for I := 0 to 5 do
begin
ListItem := ListView1.Items.Add;
ListItem.Caption := 'Item ' + IntToStr(I);
ListItem.SubItems.Add('Detail of Item ' + IntToStr(I));
// 可以根据需要添加更多子项
end;
finally
ListView1.Items.EndUpdate;
end;
end; 本帖最后由 冥界3大法王 于 2024-3-11 16:56 编辑
@wyw6813
我试着把你的代码的控件名修改了一下,没报错,也没刷新。
然后编译debug版,32位发布版本,64位的竟然把IDE卡死了。
控件需要在此下载:https://www.alphaskins.com/dwnld.php不然没有sShellListView1这个控件哟~~
procedure TForm2.Button1Click(Sender: TObject);
var
ListItem: TListItem;
I: Integer;
begin
sShellListView1.Items.BeginUpdate;
try
for I := 0 to 5 do
begin
ListItem := sShellListView1.Items.Add;
ListItem.Caption := 'Item ' + IntToStr(I);
ListItem.SubItems.Add('Detail of Item ' + IntToStr(I));
// 可以根据需要添加更多子项
end;
finally
sShellListView1.Items.EndUpdate;
end;
sShellListView1.Refresh;
end;
应该你说的对。这个控件里这部分帮助的方法啥的说的极少,应该是继承关系。
页:
[1]