2

TListView に潜在的なバグを発見したと思います。

再現手順: 新しい VCL フォーム アプリケーションを作成し、TListView を追加して、その ViewStyle を vsReports に設定します。ボタンを2つ追加

ボタン1:

procedure TForm1.Button1Click(Sender: TObject);
var
  lCol: TListColumn;
begin
  lcol :=   ListView1.Columns.Add;
  lcol.Caption := 'name';
  lcol :=   ListView1.Columns.Add;
  lcol.Caption := 'name2';
  lcol :=   ListView1.Columns.Add;
  lcol.Caption := 'name3';
end;

ボタン 2:

procedure TForm1.Button2Click(Sender: TObject);
begin
  ListView1.Columns.Delete(1);
end;

結果: 列は削除されますが、最後の列のキャプションは失われます。これは、さらに列を追加し、他の列の間にある列を削除する (または最初の列を削除する) 場合にも発生します。最後の列のキャプションは常に空です。

XE3を使用しています。見逃したものはありますか?

ありがとう

編集: QCリンク

潜在的な重複

4

2 に答える 2

4

これには、質問で報告されたものよりも多くのものがあります(最後にもっとあります)。

これはあなたの前の質問に関連しています。その質問には、列を追加した後に列を移動したときに、リストビューコントロールが列とアイテム/サブアイテム間のマッピングを失うことが含まれていました。移動時に列のsをcomctrls.pas保持することを含む可能な修正を提案しました。FOrderTagVCLでは、列が移動されるたびに、列の現在の位置を無視して、'FOrderTag'がゼロから構築されていました。

次に、バグレポートを提出し、回避策として可能な修正を送信すると、そのままチェックインされます。ここで発見した問題は、FOrderTag各列を保持してから中央から列を削除すると、穴が作成されることです。これらはもはや連続していません(たとえば、それぞれの順序タグを持つ列0、1、2がある場合は、削除します。列1で、注文タグ0と2)を持つ2つの列があります。どうやら、ネイティブコントロールはこれを好きではありません。

再びVCLを変更すると、カラムを削除するときに考えられる穴をすべて削除できます。以下は、質問へのコメントに記載されている欠落しているキャプションを含む列のサイズを変更/移動するときに、欠落しているキャプションとAVを処理しているようです。

destructor TListColumn.Destroy;
var
  Columns: TListColumns;
  i: Integer; //+
begin
  Columns := TListColumns(Collection);
  if TListColumns(Collection).Owner.HandleAllocated then
    ListView_DeleteColumn(TListColumns(Collection).Owner.Handle, Index);
//{+
  for i := 0 to Columns.Count - 1 do
    if Columns[i].FOrderTag > FOrderTag then
      Dec(Columns[i].FOrderTag);
//}
  inherited Destroy;
  Columns.UpdateCols;
end;


ここで、質問で報告されていないことに戻ると、いくつかのサブアイテムが挿入されている場合、それらがそれらの位置を保持していることに気付くでしょう。IOW列とサブアイテム間のマッピングは失われます。あなたの見方が違う可能性がありますが、削除された列のサブアイテムは失われるはずです。残念ながら、これを達成する方法を見つけることができませんでした。


編集: VCLに簡単に統合/修正するものは何も考えられません。最初に挿入された列を削除することを妨げるものは何もありません。これはアイテムに対応しており、アイテムを削除すると、すべてのサブアイテムも削除されます。VCLの現在の実装では、実際には、列を削除してもアイテムデータは削除されません。これを確認するには、列を削除した後に列を追加します。新しい列の下にサブアイテムが魔法のように表示されます。

とにかく、私があなたに提案できるのは、削除された列のサブアイテムを手動で削除することです。以下は、列とそれに対応するサブアイテムを削除するためのユーティリティ手順の例です。

procedure ListViewDeleteColumn(ListView: TListView; Col: Integer);
var
  i: Integer;
  ColumnOrder: array of Integer;
begin
  SetLength(ColumnOrder, ListView.Columns.Count);
  ListView_GetColumnOrderArray(
        ListView.Handle, ListView.Columns.Count, PInteger(ColumnOrder));
  Assert(ColumnOrder[Col] <> 0, 'column with items cannot be removed');

  for i := 0 to ListView.Items.Count - 1 do
    if Assigned(ListView.Items[i].SubItems) and
        (ListView.Items[i].SubItems.Count >= Col) then
    ListView.Items[i].SubItems.Delete(ColumnOrder[Col] - 1);

  ListView.Columns.Delete(Col);
end;

最初の列を削除する場合は、アイテム/サブアイテムをどのように処理するかを決定し、それらを再構築します。

于 2012-09-21T02:11:31.090 に答える
2

以下のコードを使用して最後の列を削除すると、正常に機能します。

uses
 CommCtrl;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ListView_DeleteColumn(ListView1.Handle, 2);
end;
于 2012-09-20T13:51:48.417 に答える