2012-09-20 3 views
2

TListView에서 잠재적 인 버그를 발견했다고 생각합니다.TListView : Columns.Delete (색인) 이후의 마지막 열의 캡션이 손실되었습니다.

재현 단계 : 새 VCL Forms 응용 프로그램을 만들고 TListView를 추가하고 ViewStyle을 vsReports로 설정하십시오. 두 개의 버튼

추가

단추 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 link

potential duplicate

+0

Delphi 2009에서는 재현 할 수 없습니다. 따라서이 문제에 대해서는 QC에서 문제를 만드는 것이 더 좋습니다. – TLama

+0

ok, 아마도 이것은 XE3 기능입니다 :) 감사합니다. – torno

+0

XE2와 함께 여기에서 재현 할 수 없습니다. –

답변

4

이보고 무슨 다음이 더있다 질문 (결국 더 많이).

이것은 이전 question과 관련이 있습니다. 이 질문에는 열을 추가 한 후 열을 이동할 때 열과 항목/하위 항목 간의 매핑이 손실되는 listview 컨트롤이 관련되어 있습니다. 필자는 comctrls.pas에 대한 수정을 제안했는데, 이동시 열의 수는 FOrderTags로 유지되었습니다. VCL은 'FOrderTag'를 기반으로 칼럼이 움직일 때마다 작성되었습니다. 칼럼의 현재 위치는 무시합니다.

그러면 어떤 일이 발생합니까? bug report을 제출하고 가능한 해결 방법을 해결 방법으로 제출하면 그대로 체크인됩니다. 이제 발견 할 수있는 문제는 각 열의 FOrderTag을 보존하고 중간에서 열을 제거하면 구멍이 생깁니다. 더 이상 순차적이지 않습니다 (각 주문 태그에 0, 1 및 2 열이 있고, 열 1을 제거하면 주문 태그 0과 2가있는 2 개의 열이 생깁니다. 분명히 네이티브 컨트롤이 이것을 좋아하지 않습니다.

다시 VCL을 수정하면 열을 제거 할 때 발생할 수있는 모든 구멍을 제거 할 수 있습니다. 아래 질문은 comment에 언급 된 누락 된 캡션이있는 열의 크기를 조정하거나 이동할 때 누락 된 캡션 및 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; 

: 다음 유틸리티 절차의 예는 열 및 해당 하위 항목을 삭제하는 것입니다.

+1

+1 좋은 형사 작업 –

+0

감사합니다 다시 sertac :) 어쩌면 내가이 해결 방법을 이번에는 제안하지 않을 것이며 이번에는 그들의 일을하게 ... 아마 그들은 또한 하위 항목을 수정합니다. 너는 맞다. 칼럼에 연결된 서브 아이템도 역시 삭제되어야한다. – torno

+0

@torno - 버그 리포트로 어떤 일을하는지 벤더가 결정할 것이다. 하지만 지금은 절반 밖에 안되기 때문에 보고서에 넣을만한 가치가 있다고 생각하지 않습니다. 천만에요! –

2

이 작품을 좋아 다음은 코드를 사용하여 마지막 열을 삭제하는 경우 :

uses 
CommCtrl; 

procedure TForm1.Button3Click(Sender: TObject); 
begin 
    ListView_DeleteColumn(ListView1.Handle, 2); 
end; 
+0

이 Columns.Count이 매크로를 사용한 후 업데이트되지 않습니다. 어떤 제안을 어떻게 강제 업데이트 할 수 있습니까? – torno

+0

@torno에서 열은 ['TListColumns'] (http://docwiki.embarcadero.com/Libraries/en/Vcl.ComCtrls.TListColumns) 컬렉션 (열을 삭제해야 함)에 저장됩니다. ['ListView_DeleteColumn'] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb761236 (v = vs.85) .aspx) Windows API 매크로를 사용하여 열을 직접 삭제하므로 컬렉션이 업데이트되지 않았습니다. 이 대안을 사용하면 콜렉션 동기화가 중단됩니다. 다른 말로하면, 그것은 단지 나쁜 해결책 일뿐입니다. – TLama

+0

목표는 마지막 열을 삭제하지 않는 것이 었습니다. 목표는 * 마지막 열을 제외한 모든 항목을 지우고 마지막 열을 표시하고 정상적으로 작동시키는 것입니다. –

관련 문제