在 Delphi 11 Alexandria 的 Windows 10 中的 32 位 VCL 應用程式中,我有TListView兩列,客戶端與表單對齊。我正在使用此代碼來處理 ListView Header 中的排序箭頭:
procedure TformMain.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
FSortedColumn := Column.Index;
case FSortedColumn of
0: FColumn0SortedUp := not FColumn0SortedUp;
1: FColumn1SortedUp := not FColumn1SortedUp;
end;
SetListHeaderSortArrow(FSortedColumn);
end;
procedure TformMain.SetListHeaderSortArrow(const aColumnIndex: Integer);
begin
var Header: HWND;
var Item: Winapi.CommCtrl.THDItem;
case aColumnIndex of
0:
begin
Header := Winapi.CommCtrl.ListView_GetHeader(ListView1.Handle);
Winapi.Windows.ZeroMemory(@Item, SizeOf(Item));
Item.Mask := Winapi.CommCtrl.HDI_FORMAT;
Winapi.CommCtrl.Header_GetItem(Header, 0, Item);
Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN); // remove both flags
if FColumn0SortedUp then
Item.fmt := Item.fmt or HDF_SORTUP // include the sort ascending flag
else
Item.fmt := Item.fmt or HDF_SORTDOWN; // include the sort descending flag
Header_SetItem(Header, 0, Item);
end;
1:
begin
Header := Winapi.CommCtrl.ListView_GetHeader(ListView1.Handle);
Winapi.Windows.ZeroMemory(@Item, SizeOf(Item));
Item.Mask := Winapi.CommCtrl.HDI_FORMAT;
Winapi.CommCtrl.Header_GetItem(Header, 1, Item);
Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN); // remove both flags
if FColumn1SortedUp then
Item.fmt := Item.fmt or HDF_SORTUP // include the sort ascending flag
else
Item.fmt := Item.fmt or HDF_SORTDOWN; // include the sort descending flag
Header_SetItem(Header, 1, Item);
end;
end;
end;
procedure TformMain.ListView1Resize(Sender: TObject);
begin
// This gets inexplicably automatically executed 3 times at program start!!
// This must be in OnResize, otherwise the sort-arrows get hidden when resizing the ListView:
SetListHeaderSortArrow(FSortedColumn);
end;
當我點擊 SECOND 列的列標題時,出現了第二列的排序箭頭,但第一列的排序箭頭并沒有消失!只有當我調整 ListView 的大小(通過調整表單的大小)時,第一列上的排序箭頭才會消失。那么如何在單擊第二列標題時使第一列上的排序箭頭立即消失?
uj5u.com熱心網友回復:
更改標志時,在將標志添加到新列之前,您不會從先前選定的列中洗掉標志。
嘗試更多類似的東西:
private:
FColumnSortedUp: array[0..1] of Boolean;
FSortedColumn: Integer;
...
procedure TformMain.FormCreate(Sender: TObject);
begin
FSortedColumn := -1;
end;
procedure TformMain.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
if FSortedColumn <> -1 then
SetListHeaderSortArrow(FSortedColumn, False);
if FSortedColumn = Column.Index then
FColumnSortedUp[FSortedColumn] := not FColumnSortedUp[FSortedColumn];
else
FSortedColumn := Column.Index;
SetListHeaderSortArrow(FSortedColumn, True);
// sort ListView items as needed...
end;
procedure TformMain.SetListHeaderSortArrow(const aColumnIndex: Integer;
const aEnabled: Boolean);
var
Header: HWND;
Item: THDItem;
begin
Header := ListView_GetHeader(ListView1.Handle);
ZeroMemory(@Item, SizeOf(Item));
Item.Mask := HDI_FORMAT;
Header_GetItem(Header, aColumnIndex, Item);
Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN); // remove both flags
if aEnabled then
begin
if FColumnSortedUp[aColumnIndex] then
Item.fmt := Item.fmt or HDF_SORTUP // include the sort ascending flag
else
Item.fmt := Item.fmt or HDF_SORTDOWN; // include the sort descending flag
end;
Header_SetItem(Header, aColumnIndex, Item);
end;
另請注意,在調整ListView大小時排序箭頭不會消失,而是在調整列大小時。因此,您必須掛鉤 ListView 來處理HDN_ENDTRACK通知,以檢測每列何時調整大小,例如:
private
...
OldWndProc: TWndMethod;
procedure ListViewWndProc(var Message: TMessage);
...
uses
..., Winapi.Messages, Winapi.CommCtrl;
procedure TformMain.FormCreate(Sender: TObject);
begin
...
OldWndProc := ListView1.WindowProc;
ListView1.WindowProc := ListViewWndProc;
end;
procedure TformMain.ListViewWndProc(var Message: TMessage);
begin
OldWndProc(Message);
if Message.Msg = WM_NOTIFY then
begin
if TWMNotify(Message).NMHdr.code = HDN_ENDTRACK then
begin
if PHDNotify(TWMNotify(Message).NMHdr).Item = FSortedColumn then
SetListHeaderSortArrow(FSortedColumn, True);
end;
end;
end;
uj5u.com熱心網友回復:
我找到了解決問題的解決方法:
procedure PALockWinControl(const WC: Vcl.Controls.TWinControl; ALock: Boolean);
begin
if (not Assigned(WC)) or (WC.Handle = 0) then EXIT;
if ALock then
WC.Perform(WM_SETREDRAW, 0, 0)
else
begin
WC.Perform(WM_SETREDRAW, 1, 0);
RedrawWindow(WC.Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
end;
end;
procedure MyRedrawWorkaround;
begin
with formMain do
begin
PALockWinControl(ListView1, True);
try
ListView1.Align := alNone;
ListView1.Width := lvMRUProjects.Width - 1;
ListView1.Align := alClient;
finally
PALockWinControl(ListView1, False);
end;
end;
end;
procedure TformMain.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
FSortedColumn := Column.Index;
case FSortedColumn of
0: FColumn0SortedUp := not FColumn0SortedUp;
1: FColumn1SortedUp := not FColumn1SortedUp;
end;
SetListHeaderSortArrow(FSortedColumn);
MyRedrawWorkaround;
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/406493.html
標籤:
上一篇:如何在UTF8編碼RadStudio/Delphi中將JSONObject保存到json檔案
下一篇:決議JSON中的字串陣列
