문제

2 열 TableLayoutPanel이 포함 된 사용자 컨트롤이 있으며 명령을 수락하여 별도의 컨트롤로 선택한 항목의 세부 사항을 표시하기 위해 행을 동적으로 추가합니다. 따라서 사용자는 다른 컨트롤 (DataGridView)에서 행을 선택하고 DatagridView의 선택한 시합 변경 이벤트 핸들러에서 세부 사항 컨트롤을 지우고 새 선택된 항목의 모든 행을 재생합니다 (완전히 다른 세부 사항이있을 수 있습니다. 이전에 선택한 항목에서 표시). 이것은 잠시 동안 잘 작동합니다. 그러나 선택한 아이템에서 다른 항목에서 다른 아이템으로 오랫동안 계속 이동하면 새로 고침이 매우 느려집니다 (각각 3-5 초). 그것은 내가 모든 것을 제대로 처분하지 않는 것처럼 들리지만, 내가 놓친 것을 알 수는 없습니다. TableLayoutPanel을 지우기위한 내 코드는 다음과 같습니다.

private readonly List<Control> controls;

public void Clear()
{
    detailTable.Visible = false;
    detailTable.SuspendLayout();
    SuspendLayout();
    detailTable.RowStyles.Clear();
    detailTable.Controls.Clear();
    DisposeAndClearControls();
    detailTable.RowCount = 0;
    detailTable.ColumnCount = 2;
}

private void DisposeAndClearControls()
{
    foreach (Control control in controls)
    {
        control.Dispose();
    }
    controls.Clear();
}

그리고 다음 세부 사항 디스플레이를 위해 원하는 모든 컨트롤을 TableLayoutPanel에로드하면 다음은 다음과 같습니다.

public void Render()
{
    detailTable.ResumeLayout(false);
    detailTable.PerformLayout();
    ResumeLayout(false);
    detailTable.Visible = true;
}

나는 TableLayoutPanel 내부에 레이블 (및 텍스트 상자가 거의 거의 없음)을 사용하지 않으며, 제어 목록에 레이블과 텍스트 상자를 추가 할 때 컨트롤 목록에 추가합니다. 나는 DetailTable.controls를 반복하고 그런 식으로 처리하려고 시도했지만 컨트롤의 절반을 놓치는 것처럼 보였습니다 (디버거에서 밟아서 결정). 이런 식으로 나는 그들 모두를 얻는다는 것을 압니다.

드로잉 성능을 향상시키기위한 제안에 관심이 있지만 특히 여러 선택에 비해 열화를 일으키는 원인.

도움이 되었습니까?

해결책 3

각 선택 변경에 대한 새 버전의 사용자 컨트롤을 구성하도록 포함 양식을 변경했습니다. 그것은 오래된 것을 처분하고 새로운 것을 구성합니다. 이것은 잘 수행되는 것 같습니다. 나는 원래 공연상의 이유로 단 하나의 재사용으로 갔다. 분명히 그것은 성능을 향상시키지 않습니다. 그리고 내가 오래된 것을 처분하고 새로운 것을 만들면 성능은 문제가되지 않습니다.

불행히도 TableLayoutPanel은 그런 식으로 누출됩니다.

다른 팁

TableLayoutPanel에서 상속하는 사용자 정의 컨트롤을 사용하고 DoubleBuffered 속성을 True에 설정하고, 특히 행을 동적으로 추가하거나 제거 할 때 훌륭하게 작동합니다.

public CustomLayout()
{
   this.DoubleBuffered = true;
   InitializeComponent();
}

TableLayout과 비슷한 문제가있었습니다. 내가 사용했다면 TableLayout.controls.clear () 방법, 어린이 컨트롤은 배치되지 않았지만 정제를 지우지 않고 단순히 탁자를 삭제했을 때 누출이 멈췄습니다. 돌이켜 보면 분명한 방법을 사용했습니다. 예방하다 어떤 종류의 누출.

명확하게, 명확한 방법은 컨트롤을 명시 적으로 폐기하지 않는다 (TableLayout에서 제거했다는 사실이 당신이 그들과 함께 완료되었음을 의미하지 않기 때문에 의미가 있습니다), Tablelayout에서 자식 컨트롤을 제거하는 것은 청소 루틴이 폐기하는 것을 방지합니다. 레이아웃 테이블 자체가 배치 될 때의 어린이는 더 이상 그들에 대해 알지 못합니다).

내 추천 : 삭제 세부 사항 .controls.clear (); 줄, 부모의 세부 사항 자체를 제거하십시오. 통제 수단 수집 및 폐기 한 다음 다음 라운드에 새로운 TableLayout을 만듭니다. 또한 필요하지 않기 때문에 처분 시체 콘트롤 방법을 완전히 잃어 버립니다. 내 경험상, 그것은 잘 작동했습니다.

이런 식으로, 당신은 더 이상 전체 사용자 컨트롤을 재활용 할 필요가 없지만 내부의 탁자 만 가능합니다.

나는 같은 문제에 직면했고 너무 많이 바꾸지 않고 좋은 방법을 찾았습니다.

vb.net에서

Dim tp As Type = tlpMyPanel.GetType().BaseType
Dim pi As Reflection.PropertyInfo = _
    tp.GetProperty("DoubleBuffered", _ 
    Reflection.BindingFlags.Instance _
    Or Reflection.BindingFlags.NonPublic)
pi.SetValue(tlpMyPanel, True, Nothing)

또는 C#에서 :

Type tp = tlpMyPanel.GetType().BaseType;
System.Reflection.PropertyInfo pi = 
    tp.GetProperty("DoubleBuffered",
    System.Reflection.BindingFlags.Instance 
    | System.Reflection.BindingFlags.NonPublic);
pi.SetValue(tlpMyPanel, true, null);

불행히도, 내가 제공 할 수있는 유일한 조언은 당신의 컨트롤 배치를 직접 돌보는 것입니다. 내 경험상 .NET TableLayoutPanel은 매우 유용하지만 무언가를 새는 것이고 자라면서 느리게 느려집니다 (그리고이 시점에 도달하기 위해서는 불합리한 수의 셀이 필요하지 않습니다). 이 행동은 디자이너에서도 볼 수 있습니다.

TableLayoutPanel.controls.clear ()는 나에게 잘 작동합니다. 아마도 표시된 것과는 다른 탭에서 지우기 때문에 아마도 잘 작동합니다.

List<Control> controls = new List<Control>();
foreach (Control control in tableLayoutPanelEnderecoDetalhes.Controls)
{
    controls.Add(control);
}

foreach (Control control in controls)
{
    control.Dispose();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top