2011-07-06 1 views
6

WinForms TreeView을 사용 중이며 AfterLabelEdit 이벤트에 대한 반응입니다. 다음은 코드의 일부입니다.TreeNode.BeginEdit()의 문제점

사용자가 잘못된 문자를 자동으로 수정하고 싶지 않을 때 노드는 편집 모드를 유지하지 않습니다. 이 문제를 해결할 방법이 있습니까? 당신은 BeginEdit()을 만드는 시도 할 수

답변

2

몇 가지를 원하는 경우 "나쁜 문자를"교체는 :이 제기 된 후

  1. AfterLabelEdit 이벤트는 항상 편집 모드를 종료 심지어 이벤트 핸들러 중간에 BeginEdit으로 전화를 걸어도 마찬가지입니다. TreeView.BeginInvoke을 사용하면 TreeView가 그 일을 한 후에 EditMode가 다시 시작되도록함으로써 "도약"할 수 있습니다. (참고 :이 새 스레드 또는 경쟁 조건을 만들지 않습니다, 그것은 단지 1 창 메시지에 대한 메서드를 지연합니다.)이 이벤트의 일부 문제에 대한 자세한 정보가 있습니다 here (비록 내가 생각하는 것이 더 나쁘다고 생각합니다 해결책).
  2. e.Label은 사용자가 변경하지 않은 경우 null입니다. 따라서 BeginInvoke로 "뛰어 넘을 때"는 사용자가 변경하지 않은 것처럼 보이므로이 경우도 처리해야합니다.
  3. BeginInvoke는이 경우 적절한 해결 방법이므로이 상황에서 매우 안정적이어야합니다.
  4. 이 나를 위해 아주 잘 작동

는 .NET 2.0에서 테스트 :

private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) 
    { 
     //we have to handle both the first and future edits 
     if ((e.Label != null && e.Label.Contains("|") || (e.Label == null && e.Node.Text.Contains("|")))) 
     { 
      if (WantAutofix()) 
      { 
       e.CancelEdit = true; 

       if(e.Label != null) 
        e.Node.Text = e.Label.Replace('|', '_'); 
       else 
        e.Node.Text = e.Node.Text.Replace('|', '_'); 
      } 
      else 
      { 
       //lets the treeview finish up its OnAfterLabelEdit method 
       treeView1.BeginInvoke(new MethodInvoker(delegate() { e.Node.BeginEdit(); })); 
      } 
     } 

    } 

    private bool WantAutofix() 
    { 
     return MessageBox.Show("You entered a |, you want me to AutoFix?", String.Empty, MessageBoxButtons.YesNo) == DialogResult.Yes; 
    } 
0

비동기 적으로 발생합니다

private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) 
    { 
     if (e.Label.Contains("|")) 
     { 
      if (WantAutofix()) 
      { 
      } 
      else 
      { 
       e.CancelEdit = true; 
       BeginInvoke(new ActionDelegate(new NodeBeginEditAsync(e.Node).Execute)); 
       return; 
      } 
     } 
    } 
public class NodeBeginEditAsync 
{ 
    private readonly TreeNode _node; 

    public NodeBeginEditAsync(TreeNode node) 
    { 
     _node = node; 
    } 

    public void Execute() 
    { 
     _node.BeginEdit(); 
    } 
} 

public delegate void ActionDelegate(); 

CancelEdit 새로운 BeginEdit가 인수를 시도하기 전에 완료 할 수있는 기회가 주어집니다 그런 식으로.

+0

별로 옵션 : 나는 .NET 2.0을 사용하고,이 신뢰할 수있는 솔루션입니다 없습니다. – Migol

+0

왜 그렇게 생각하니? (아마도 Action() 구문을 사용할 수는 없지만 BeginInvoke는 .NET 2.0에서 작동합니다. – jlew

+0

Simple. 이 솔루션이 작동한다면 우리는 경합 조건을 갖게됩니다. 스레드는 CancelEdit - BAD 이전에 만들어지고 실행 된 후에 실행됩니다. – Migol

0

사용지며 EndEdit와 사용자가 자동 ​​수정을 염두에 두어야

+0

당신은 나를 알지 못했습니다. 편집 모드로 유지하고 싶다면 직접 수정해야합니다. 문제가 있습니다. – Migol

0
try this...  
TreeNode node = tv.SelectedNode; 
        if (tv.SelectedNode.Parent == null) 
        { 
         node.TreeView.LabelEdit = false; 
        } 
        else 
        { 
         node.Text = FieldName.Text; 
         if (node == null) { return; } 
         node.TreeView.LabelEdit = true; 
         node.BeginEdit(); 
        }