【问题标题】:How do I prevent a ListView header from obscuring the top of the first group?如何防止 ListView 标头遮挡第一组的顶部?
【发布时间】:2015-09-16 18:11:24
【问题描述】:

我使用 Delphi XE,我想让一个标准的 ListView 表现得像我想要的那样。 我希望列表视图是 vsReport,这样我就可以为我的项目设置组。 在设计时,我创建了列(一个名为 Topic 的列)、两个组以及每个组的一些项目。

在设计时 ListView 看起来很棒,但在运行时,我的第一组不知何故部分隐藏在列标题下。以下是图片:

在设计时:

运行时:

这是我的 DFM

object Form2: TForm2
  Left = 326
  Top = 150
  Caption = 'Form2'
  ClientHeight = 636
  ClientWidth = 1289
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ListView1: TListView
    Left = 0
    Top = 0
    Width = 205
    Height = 636
    Align = alLeft
    Columns = <
      item
        Caption = 'Topic'
        Width = 200
      end>
    ColumnClick = False
    DoubleBuffered = True
    FullDrag = True
    Groups = <
      item
        Header = 'First group'
        GroupID = 0
        State = []
        HeaderAlign = taLeftJustify
        FooterAlign = taLeftJustify
        Subtitle = 'Options bellow'
        TitleImage = 1
      end
      item
        Header = 'Settings'
        GroupID = 1
        State = [lgsNormal]
        HeaderAlign = taLeftJustify
        FooterAlign = taLeftJustify
        Subtitle = 'Other options here'
        TitleImage = 0
      end>
    HideSelection = False
    HotTrack = True
    HotTrackStyles = [htUnderlineCold, htUnderlineHot]
    Items.ItemData = {
      059E000000030000000000000000000000FFFFFFFF0000000000000000000000
      000A4600690072007300740020006900740065006D000100000001000000FFFF
      FFFF0000000000000000000000000B5300650063006F006E0064002000690074
      0065006D000200000002000000FFFFFFFF000000000100000000000000134600
      69007300720074002000730065007400740069006E0067007300200069007400
      65006D00}
    GroupView = True
    RowSelect = True
    ParentDoubleBuffered = False
    ShowWorkAreas = True
    TabOrder = 0
    ViewStyle = vsReport
    OnClick = ListView1Click
    ExplicitTop = 8
    ExplicitHeight = 497
  end
end

如何防止这种情况发生?

【问题讨论】:

    标签: delphi listview delphi-xe


    【解决方案1】:

    即使在 Delphi 10 Seattle 中也存在这种行为。我不确定是什么原因造成的,但您可以通过对列表视图属性进行重大更改,然后恢复该更改来解决它。这似乎足以让列表视图赶上。例如,这样就足够了:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListView1.ViewStyle := vsIcon;
      ListView1.ViewStyle := vsReport;
    end;
    

    但这有点过头了。深入研究这段代码有什么影响,它是重新创建窗口的关键。可以这样完成:

    type
      TProtectedHackListView = class(TListView);
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      TProtectedHackListView(ListView1).RecreateWnd;
    end;
    

    甚至重新创建表单,这反过来又会重新创建孩子:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      RecreateWnd;
    end;
    

    【讨论】:

    • RecreateWnd() 上的 TListView 就足够了。更改 ViewStyle 太过分了,重新创建窗体的窗口及其所有子控件也是如此。
    • 谢谢你们。 Remy Lebeau,你的评论也很有帮助。谢谢
    • 作为测试,我创建了一个TForm,其CreateWnd() 方法直接调用了与TListView 相同的API,生成的ListView 没有出现问题。很奇怪。也许TListView 正在做一些额外的事情来混淆底层窗口,它如何管理与其内置标题控件相关的内容。
    • @RemyLebeau 更改视图样式是一种避免对受保护方法进行有点骇人听闻的调用的方法。这是我尝试的第一件事。它成功了,因为它重新创建了窗口句柄......
    • @DavidHeffernan:是的,它确实重新创建了窗口 - 两次,并且还做了很多不必要的工作来设置图标视图,只是为了将其拆下以再次设置报告视图。最好只重新创建一次并让它设置现有视图。
    猜你喜欢
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2017-11-23
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多