코드로 WPF 컨텍스트 메뉴 오픈 방법 :: WPF ContextMenu Open in Code

윈도우즈 어플리케이션에서 마우스 오른쪽 클릭으로 팝업되는 메뉴를 'Context Menu'라고 부르는데
XAML에서는 System.Windows.Controls 네임스페이스아래 ContextMenu 클래스로 존재합니다.

WPF어플리케이션에서는 FrameworkElement라면 어떤 컨트롤이든지 ContextMenu를 설정할 수 있는데요.
예를들어 버튼에 컨텍스트 메뉴를 설정하고 싶다면 xaml에서는 아래와 같이

<Button x:Name="ui_button" Content="테스트 Button" >
 <Button.ContextMenu>
 <ContextMenu x:Name="contextMenu" >
  <MenuItem Header="menu 1." />
  <MenuItem Header="menu 2." />
 </ContextMenu>
 </Button.ContextMenu>
</Button>


버튼컨트롤의 ContextMenu라는 의존속성에 ContextMenu를 할당해 두면 사용자 마우스 오른쪽버튼 이벤트에
반응하여 자동으로 컨텍스트 메뉴를 띄워주게됩니다.

그런데 가~끔 이 컨텍스트메뉴를 사용자 개입없이 자동으로 띄워야 할 필요가 있는데요..
코드에서 컨텍스트 메뉴를 띄우는건 contextMenu.IsOpen=true; 라는 짧은 코드로 가능합니다...만!!

이런걸 원한게 아닌데..

이런걸 원한게 아닌데... 끙..


예.. 컨텍스트메뉴가 버튼에서 팝업되는게아니라 마우스 포인터 옆에서 팝업되어버립니다.
컨텍스트메뉴, 드롭다운, 툴팁등은 팝업시스템으로 동작하는 또다른 윈도우이기 때문에 나타나는 현상입니다.
WPF의 팝업 시스템에대한 자세한 이야기는 아래 MSDN의 글을 참조하시도록 하구요..
http://msdn.microsoft.com/ko-kr/library/system.windows.controls.primitives.popup.aspx(새 창으로 열기)
그럼, 어떻게하면 우리가 바라는대로 버튼 옆에 컨텍스트 메뉴를 띄울 수 있냐...
ContextMenu의 PlacementRectangle, HorizontalOffset ,VerticalOffset 의존속성을 설정하면
가능해 집니다.

//컨텍스트 메뉴가 열릴 기준이되는 UI엘리먼트의 화면좌상단으로부터 위치(point)를 구합니다.
Point targetPoint = ui_button.PointToScreen( new Point(0,0) ); 

//컨텍스트 메뉴가 popup될 영역과 기준위치를 설정합니다 contextMenu.PlacementRectangle = new Rect(targetPoint, new Size( ui_button.Width, ui_button.Height)); contextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.RelativePoint; //offset을 주시구요… contextMenu.HorizontalOffset = 10; contextMenu.VerticalOffset = 10;

//컨텍스트 메뉴를 여시면 됩니다. contextMenu.IsOpen = true;



자.. 위와같이 수정 후 실행 하시면..
짜잔~

짜잔~


예 원하는 결과대로 되었습니다.
이 포스팅의 요지는 위에서 설명한 팁이 될수도 있겠지만 그보다는 'WPF의 팝업시스템의 이해' 정도가 되겠군요. ^^

2009/03/03 15:29 2009/03/03 15:29
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. Blog Icon
    백미란

    contextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.RelativePoint;
    이렇게 하면 오른쪽버튼 클릭했다가 다시 왼쪽버튼을 눌렀을때 이상한 좌표에서 컨텍스트 메뉴가 뜨네요~
    Con.Placement = System.Windows.Controls.Primitives.PlacementMode.AbsolutePoint;
    이렇게 해야 정상으로 나와요 ^^ 강의 감사합니다~
    그런데 혹시 오른쪽 버튼 눌렀을때 컨텍스트 메뉴가 뜨지 않게 막는 방법도 있나요 ?
    그리고 바탕화면 쉘 컨텍스트 메뉴처럼 정보를 읽어와 뜨게 하는 방법이 있는지도 궁금합니다..

  2. 하하. 좋은 정보로 ^^) 프로젝트 이슈 하나 풀어갑니다.

  3. Blog Icon
    써니

    헐....
    잘 보고 갑니다.. 쩝... 처음으로 뜨네요 ... ㅋ