2010-08-20 1 views
1

Tree View 컨트롤의 AfterCheck 이벤트는 그 아래에있는 모든 하위 노드를 검사하고 항목이 선택되면 실행 단추를 사용합니다.CheckBoxes가있는 느린 TreeNode [다량]

1346 void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) { 
1347 if (!e.Node.Checked) return; 
1348 foreach (TreeNode sub in e.Node.Nodes) { 
1349  sub.Checked = e.Node.Checked; 
1350 } 
1351 RunButton.Enabled = IsANodeChecked(); 
1352 } 

1429 static bool IsANodeChecked(TreeNode node) { 
1430 if (node.Checked) return true; 
1431 foreach (TreeNode sub in node.Nodes) { 
1432  if (IsANodeChecked(sub)) { 
1433  return true; 
1434  } 
1435 } 
1436 return false; 
1437 } 

4881 개의 하위 노드가있을 때 루트 노드를 확인하면 약 7 초 동안 GUI가 중단됩니다.

한 번만 IsANodeChecked (Line 1351에서)를 호출하면되지만 모든 트리 노드가 처리 될 때까지 비활성화하는 방법을 알지 못합니다.

그리고 이것을 모니터링하기 위해 제 양식에 타이머를 갖고 싶지 않습니다.

누구나 간단하고 분명한 해결책을 알고 있습니까?

+0

코드를 컴파일 할 수 없습니다. –

답변

0

이 아이디어 도움을하지만, 나는 하나의 부울 변수 추가하여 일한 다른 뭔가를 사용 :

bool _treeNodeFirst = false;

을 ... 일시적으로 컨트롤의 배경색을 수정하는 전에 검사 이벤트가 시작 컨트롤 플래그 역할을 체인의 전자 통풍구 :

1273 void TreeNode_BeforeCheck(object sender, TreeViewCancelEventArgs e) { 
1274 if (!_treeNodeFirst) { 
1275  _treeNodeFirst = true; 
1276  e.Node.BackColor = Color.Silver; 
1277 } 
1278 } 

1346 void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) { 
1347 if (e.Node.Checked) { 
1348  foreach (TreeNode sub in e.Node.Nodes) { 
1349  sub.Checked = e.Node.Checked; 
1350  } 
1351 } 
1352 if (e.Node.BackColor == Color.Silver) { 
1353  e.Node.BackColor = Color.Empty; 
1354  RunButton.Enabled = IsANodeChecked(); 
1355  _treeNodeFirst = false; 
1356 } 
1357 } 

1429 static bool IsANodeChecked(TreeNode node) { 
1430 if (node.Checked) return true; 
1431 foreach (TreeNode sub in node.Nodes) { 
1432  if (IsANodeChecked(sub)) { 
1433  return true; 
1434  } 
1435 } 
1436 return false; 
1437 } 

이 노드 그룹이 한 번에 선택 될 때 IsANodeChecked(TreeNode) 한 번만 실행되도록 (내가 지금 볼 수있는) 가장 좋은 방법이 될 것으로 보인다.

그러나 나는 지미 호파의 생각을 정말 좋아한다. 나는 아마 그것을 코드에 추가 할 것이다.

모두에게 감사드립니다! ~ 조

1

때때로 이러한 경우를 처리하기 위해 Timer을 사용합니다. 타이머를 추가하고 Tick 이벤트 처리기를 설정하여 IsANodeChecked을 호출하고 버튼을 활성화/비활성화합니다. 짧은 간격 (아마도 ~ 100 밀리 초)을주고 사용하지 마십시오. 그런 다음 Stop을 호출하고 AfterCheck 이벤트 처리기의 타이머에서 Start을 호출합니다. 이로 인해 AfterCheck에 대한 각 호출에 대해 타이머가 다시 시작되지만 이벤트 핸들러는 Start 호출 이후에 특정 시간이 경과 한 경우에만 호출됩니다. 이는 AfterCheck의 마지막 호출 이후에 호출되지 않음을 의미합니다.

100ms는 컴퓨터가 작동하는 데 오랜 시간이 걸리지 만 사용자에게는 즉각적인 것처럼 보입니다.

Windows 탐색기에서 비슷한 동작을 볼 수 있습니다. 키보드를 사용하여 폴더 트리에서 빠르게 탐색하는 경우 잠시 동안 트리의 폴더에 머물러 있지 않으면 폴더 내용이있는 오른쪽 창은 업데이트되지 않습니다.

+0

더 나은 방법이 없다면이 응용 프로그램에서 또 다른 타이머를 구현해야 할 수도 있습니다. 그래도 나는하지 않을 것이다. – jp2code

+0

@ jp2code : 응용 프로그램이 이미 타이머 강렬하다면, 나는 당신의 주저를 보았습니다. 나는 그들을 피하고 그 특별한 경우를 위해 그들을 구하는 경향이 있습니다. –

2

전체를 반복하는 무언가를 찾지 않고 RunButton을 활성화하거나 비활성화하는 확인란에 이벤트 처리기를 추가하십시오.

확인란이 선택된 경우 먼저 확인란을 선택하고 체크 상자가 비어있을 때까지 RunButton을 비활성화하지 마십시오. 등이이 선택 해제 목록, 여기

에서 제거가 가지 내가 쓰는 얼마나, 이것은 단지 내가 뭔가 놓칠 경우 정말 미안 해결 해보려고 하는것되는 것 :

private int _checkedCheckboxes; 

void AddCheckBox() 
{ 
    if (_checkedCheckBoxes++ == 1) RunButton.Enabled = true; 
} 

void RemoveCheckBox() 
{ 
    if (_checkedCheckBoxes-- == 0) RunButton.Enabled = false; 
} 

void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) 
{ 
    if (e.Node.Checked) 
    { 
     AddCheckBox(); 
     return; 
    } 

    RemoveCheckBox(); 
} 
+0

트리 노드는 데이터베이스의 모델 번호 (일련 번호)를 기반으로 수동으로 생성됩니다. 수동으로 생성 된 각 노드에 대해 새로운 이벤트를 생성 하시겠습니까? (5000 이벤트와 같은) 루트 노드를 검사하고 5000 개의 자식 노드가 동시에 실행되면 어떻게 될 것인가? 아이디어를 디자인하는 데 약간의 시간이 걸리므로 더 많은 것을 알고 싶습니다. – jp2code