2010-12-02 1 views
0

winform에서 작업 중이며 UI에 트리 뷰가 있습니다. 마우스 오른쪽 버튼으로 노드를 클릭하지 않아도 트리 노트가 강조 표시됩니다. (예는, 나는 다음과 같은 위치를 클릭하면 노드 1이 강조 표시됩니다),하지만 난 내가 TreeNode를 클릭하지 않았을 때 다른 컨텍스트 메뉴를 표시하기 원하기 때문에 난 정말이 동작을 좋아하지 않는다treeview 노드가 강조 표시됩니다. 노드를 오른쪽 클릭하지 않았습니다.

+ rootNode를

|_ Node1    [ Right Click Here, Node1 will be highlighted] 
    | 
    |_ Node2    [ Right Click Here, Node2 will be highlighted] 
+0

귀하의 질문을 이해할 수 있을지 확실하지 않습니다. 즉, 노드 오른쪽의 빈 공간을 클릭하면 마우스 오른쪽 버튼을 누르고있는 동안 노드가 강조 표시됩니다. –

+0

네, 맞습니다! 노드를 클릭하지 않았을 때 노드가 강조 표시되는 것을 원하지 않는다. –

답변

1

이 사용자가 노드를 클릭하지 않을 경우 하이라이트가 될 노드를 방지하기 위해 시도하고 난 단지 각각의 배경색과 데 ForeColor를 설정 노드에 트리를 추가 할 때

newNode.BackColor = treeview1.BackColor; 
newNode.ForeColor = treeview1.ForeColor; 
treeview1.Nodes.Add(newNode); 

그런 다음 MouseDown 이벤트에서 SelectedNode 속성을 다음과 같이 설정하십시오.

private void treeView1_MouseDown(object sender, MouseEventArgs e) 
{ 
     TreeNode Node = treeView1.GetNodeAt(e.Location); 
     if (Node != null && Node.Bounds.Contains(e.Location)) 
      treeView1.SelectedNode = Node; 
     else 
      treeView1.SelectedNode = null; 
} 
+0

마우스 단추를 누르고있는 동안 노드에서 선택 사각형이 계속 나타나는 것을 제외하면이 방법이 효과가 있다고 가정합니다. ('BackColor'를 변경했기 때문에) 선택 사각형을 채우지 않지만, 점선으로 된 윤곽선은 여전히 ​​존재합니다. 그러나 나는 당신이 강박 관념론적인 완벽 주의자가 아니라면 괜찮을 것이라고 생각합니다. :-) –

+0

@ 코드 그레이 : 노드를 클릭하지 않으면 점선으로 된 윤곽선을 보지 못했습니다. –

0

정확하게 이해하면 사용자가 TreeView 내의 빈 공간을 클릭하면 노드가 선택됩니다. 트리의 MouseDown-Event를 처리하고 트리의 SelectedNode 속성을 TreeView.GetNodeAt (e.Location)로 설정하면됩니다.

+0

예, 사용자가 트리 뷰 내의 빈 공간을 클릭 할 때 강조 표시된 노드를 원하지 않고 코드를 시도했지만 작동하지 않는다. –

+0

@Carlos_Liu : 나는 당신을 위해 작동하지 않는다는 것에 놀랐다. 나는 그저 나 자신을 시험해 보았다. –

+0

두 번째 생각에서 FullRowSelect를 true로 설정하면 GetNodeAt는 마우스 커서가 텍스트 옆에 있더라도 노드를 반환합니다. 어쩌면 이것은 당신이 겪고있는 문제를 설명해 줄 수 있습니까? –

4

Kevin Wienhold의 답변에 대한 귀하의 의견에 따라, 사용자는 treeview의 빈 공간을 클릭하고 선택된 노드를 선택 취소 할 수 있습니다.

당신은 TreeView 제어의 MouseDown event을 처리하고, 마우스가 노드를 포함하지 않는 위치를 통해 클릭 한 경우 nullSelectedNode property을 설정하여이 작업을 수행 할 수 있습니다.는 예를 들어, 다음 코드를 사용할 수

private void myTreeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) 
{ 
    if (myTreeView.HitTest(e.Location).Node == null) 
    { 
     myTreeView.SelectedNode = null; 
    } 
} 

이 테스트 할 수있는 지점으로 마우스 이벤트의 위치를 ​​지정, 특정 지점에 위치하는 노드를 결정하기 위해 HitTest method을 활용합니다. 사용자가 일 때 노드를 선택하는 데 다른 코드가 필요하지 않습니다.을 클릭하십시오. TreeView에 의해 자동으로 처리됩니다.


편집 : 질문에 대한 내 댓글이 표시, 나는 여전히 당신이 달성하려고하는 것과 같은 매우 불분명 해요. 실제로 노드의 측면에있는 빈 공간에서 마우스 오른쪽 버튼을 누르고있는 동안 노드가 일시적으로 강조 표시되는 것을 막으려는 경우, 상황은 좀 더 복잡해집니다.

이전에이 문제를 조사한 적이 있으며, 마우스 버튼을 누르고있는 동안 마우스를 움직일 때까지는 메시지가 수신되지 않는 경우가 있습니다 (이 경우 노드가 아니요). 어쨌든 더 이상 선택됨). 이 동작은 운영 체제에서 명시 적으로 지정되며 표준 .NET 제공 이벤트를 사용하여 쉽게 재정의 할 수 없습니다. 하루 종일 MouseDown 이벤트에서 오른쪽 버튼 클릭을 취소 할 수는 있지만이 이벤트가 제어되기 전에 노드가 Windows에서 선택 중입니다. TreeViewListView과 같은 .NET 제공 컨트롤은 다음과 같습니다. Windows API에서 제공하는 동일한 컨트롤 주위의 래퍼 (이 "select-node-while-right-button-held-down"동작 자체를 구현 함). 무엇

일, 그러나, 파생 TreeView 제어 WndProc을 무시하고 WM_RBUTTONDOWN message을 처리한다.하지만 속성을 null으로 설정하더라도 이후에 처리되지 않기 때문에 여기서는 작동하지 않습니다. Windows는 마우스 오른쪽 버튼에 대한 응답으로 노드를 자동으로 선택하므로 아무 일도하지 않아도됩니다. 기본 TreeView 컨트롤은 WM_RBUTTONDOWN 메시지를 수신하지 못합니다.

  1. 당신은 단순히 일찍 return 문을 구제하여 마우스 오른쪽 단추로 클릭 한 메시지를 취소 할 수 있습니다 : 그래서, 당신은이 문제를 처리하는 방법에 선택의 몇 가지있다. 물론 컨트롤에 실제로 전달 된 적이 없으므로 MouseDown 핸들러에서이 이벤트를 처리 할 수 ​​없게됩니다. 따라서 팝업 컨텍스트 메뉴를 표시하려면이 방법이 효과가 없을 것입니다.

    public class NewTreeView : System.Windows.Forms.TreeView 
    { 
        protected override void WndProc(ref System.Windows.Forms.Message m) 
        { 
         const int WM_RBUTTONDOWN = 0x204; 
         if (m.Msg == WM_RBUTTONDOWN) 
         { 
          return; 
         } 
         base.WndProc(ref m); 
        } 
    } 
    
  2. 당신은 기본 클래스는 메시지를 처리 ​​할 수없이 다음 방법에서 returnWM_RBUTTONDOWN 메시지에 대한 응답으로 오버라이드 (override) WndProc 방법에 상황에 맞는 메뉴를 표시하고 있습니다. 이는 첫 번째 솔루션과 똑같은 일을합니다 (마우스 오른쪽 버튼 이벤트로 인해 노드가 선택되어 표시되는 것을 방지합니다). 마우스 오른쪽 버튼을 클릭 할 때마다 컨텍스트 메뉴를 표시하거나 원하는 다른 작업을 수행 할 수 있습니다 발생합니다. 물론 관련 코드가 모두 TreeView 컨트롤의 하위 클래스에 포함되어야하며 양식 UI 코드에서 처리되지 않아야 함을 의미합니다. 이는 사용자에게 편리 할 수도 있고 그렇지 않을 수도 있습니다.

    public class NewTreeView : System.Windows.Forms.TreeView 
    { 
        protected override void WndProc(ref System.Windows.Forms.Message m) 
        { 
         const int WM_RBUTTONDOWN = 0x204; 
         if (m.Msg == WM_RBUTTONDOWN) 
         { 
          //Create and show a context menu 
          var myContextMenu = new ContextMenuStrip(); 
          myContextMenu.Items.Add("First Item"); 
          myContextMenu.Items.Add("Second Item"); 
          return; 
         } 
         base.WndProc(ref m); 
        } 
    } 
    
  3. 당신 수 당신이 양식의 UI 코드에서 원하는대로 다음 처리 할 수있는 WM_RBUTTONDOWN 메시지에 대한 응답으로 사용자 정의 TreeView 클래스 raise your ownRightMouseClick 이벤트입니다. WM_RBUTTONDOWN 메시지를 기본 컨트롤 인 TreeView 컨트롤 클래스에 전달하지 않으면 앞의 두 가지 제안과 동일한 목표를 달성 할 수 있지만 양식의 UI 코드에서 마우스 오른쪽 버튼 클릭 이벤트를 처리 할 수 ​​있습니다 서브 클래스 화 된 컨트롤의 WndProc

    public class NewTreeView : System.Windows.Forms.TreeView 
    { 
        protected override void WndProc(ref System.Windows.Forms.Message m) 
        { 
         const int WM_RBUTTONDOWN = 0x204; 
         if (m.Msg == WM_RBUTTONDOWN) 
         { 
          //Raise your custom event 
          OnRightMouseClick(new EventArgs()); 
          return; 
         } 
         base.WndProc(ref m); 
        } 
    } 
    
+0

+1 : 히트 테스트를했지만 히트 테스트에서 노드가 계속 표시됩니다. 솔루션을 테스트 해 보셨습니까? – TalentTuner

+0

@Saurabh : 그래, 테스트를 거쳤습니다. 네가 무슨 말하는지는 모르겠다. 나는 노드를 선택 해제하기 위해'HitTest'를 사용하지 않고 마우스를 클릭 한 노드를 결정하고 노드를 클릭하지 않은 경우'SelectedNode' 속성을'null'로 설정합니다. 노드가 선택 해제되도록하십시오. 노드를 "표시"하지 않는 한,'TreeView'에서 노드를 제거하지 * 않는다는 것을 의미합니다.이 경우, 아니요,하지만 요청되는 것이 아닙니다. –

+0

예, 마우스를 오른쪽 클릭하면 노드가 초점을 맞추고 있습니다. –

1

나는 다른 방법을 발견했다

void treeView1_MouseDown(object sender, MouseEventArgs e) 
    { 


     TreeViewHitTestInfo h = treeView1.HitTest(e.Location); 

     if (h.Location != TreeViewHitTestLocations.Label && h.Location!= TreeViewHitTestLocations.None) 
     { 
      treeView1.SelectedNode = null; 
     } 
    } 
+0

당신이 지금 말하고있는 것을 보았습니다. 그러나 마우스 오른쪽 버튼을 누른 상태에서 질문자가 노드가 선택된 상태에서 * 멈추길 원한다고 가정하면, 이는 작동하지 않습니다. –