■ Behavior<T> 클래스를 사용해 마우스 왼쪽 버튼 클릭시 컨텍스트 메뉴를 표시하는 방법을 보여준다.
▶ MouseLeftButtonContextMenuSupportBehavior.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Interactivity; namespace TestProject { /// <summary> /// 마우스 왼쪽 버튼 컨텍스트 메뉴 지원 동작 /// </summary> public class MouseLeftButtonContextMenuSupportBehavior : Behavior<UIElement> { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 마우스 왼쪽 버튼 DOWN 허용 여부 첨부 속성 - AllowMouseLeftMouseDownProperty /// <summary> /// 마우스 왼쪽 버튼 DOWN 허용 여부 속성 /// </summary> public static readonly DependencyProperty AllowMouseLeftMouseDownProperty = DependencyProperty.RegisterAttached ( "AllowMouseLeftMouseDown", typeof(bool), typeof(MouseLeftButtonContextMenuSupportBehavior), new FrameworkPropertyMetadata(false) ); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 마우스 왼쪽 버튼 DOWN 허용 여부 구하기 - GetAllowMouseLeftMouseDown(element) /// <summary> /// 마우스 왼쪽 버튼 DOWN 허용 여부 구하기 /// </summary> /// <param name="element">UI 엘리먼트</param> /// <returns>마우스 왼쪽 버튼 DOWN 허용 여부</returns> public static bool GetAllowMouseLeftMouseDown(UIElement element) { return (bool)element.GetValue(AllowMouseLeftMouseDownProperty); } #endregion #region 마우스 왼쪽 버튼 DOWN 허용 여부 설정하기 - SetAllowMouseLeftMouseDown(element, value) /// <summary> /// 마우스 왼쪽 버튼 DOWN 허용 여부 설정하기 /// </summary> /// <param name="element">UI 엘리먼트</param> /// <param name="value">값</param> public static void SetAllowMouseLeftMouseDown(UIElement element, bool value) { element.SetValue(AllowMouseLeftMouseDownProperty, value); } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Instance //////////////////////////////////////////////////////////////////////////////// Protected #region 접착시 처리하기 - OnAttached() /// <summary> /// 접착시 처리하기 /// </summary> protected override void OnAttached() { base.OnAttached(); if(AssociatedObject != null) { AssociatedObject.AddHandler ( UIElement.PreviewMouseLeftButtonDownEvent, new RoutedEventHandler(UIElement_PreviewMouseLeftButtonDown) ); } } #endregion #region 탈착시 처리하기 - OnDetaching() /// <summary> /// 탈착시 처리하기 /// </summary> protected override void OnDetaching() { base.OnDetaching(); if(AssociatedObject != null) { AssociatedObject.RemoveHandler ( UIElement.PreviewMouseLeftButtonDownEvent, new RoutedEventHandler(UIElement_PreviewMouseLeftButtonDown) ); } } #endregion //////////////////////////////////////////////////////////////////////////////// Private #region UI 엘리먼트 프리뷰 마우스 왼쪽 버튼 DOWN 처리하기 - UIElement_PreviewMouseLeftButtonDown(sender, e) /// <summary> /// UI 엘리먼트 프리뷰 마우스 왼쪽 버튼 DOWN 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void UIElement_PreviewMouseLeftButtonDown(object sender, RoutedEventArgs e) { UIElement element = e.Source as UIElement; if(element != null) { if(true.Equals(element.GetValue(MouseLeftButtonContextMenuSupportBehavior.AllowMouseLeftMouseDownProperty))) { ContextMenu contextMenu = ContextMenuService.GetContextMenu(element); if(contextMenu != null) { MouseButtonEventArgs eventArgs = new MouseButtonEventArgs ( Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Right ); eventArgs.RoutedEvent = Mouse.MouseUpEvent; eventArgs.Source = element; InputManager.Current.ProcessInput(eventArgs); e.Handled = true; } } } } #endregion } } |
▶ TestContextMenu.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; namespace TestProject { /// <summary> /// 테스트 컨텍스트 메뉴 /// </summary> public class TestContextMenu : ContextMenu { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 메뉴 항목 클릭 이벤트 - MenuItemClickEvent /// <summary> /// 메뉴 항목 클릭 이벤트 /// </summary> public static readonly RoutedEvent MenuItemClickEvent = EventManager.RegisterRoutedEvent ( "MenuItemClickEvent", RoutingStrategy.Bubble, typeof(RoutedEventArgs), typeof(TestContextMenu) ); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - TestContextMenu() /// <summary> /// 생성자 /// </summary> public TestContextMenu() { AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(MenuItem_Click)); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private #region 메뉴 항목 클릭시 처리하기 - MenuItem_Click(sender, e) /// <summary> /// 메뉴 항목 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void MenuItem_Click(object sender, RoutedEventArgs e) { Popup popup = Parent as Popup; if(popup != null) { FrameworkElement targetElement = popup.PlacementTarget as FrameworkElement; if(targetElement != null) { targetElement.RaiseEvent(new RoutedEventArgs(TestContextMenu.MenuItemClickEvent, e.Source)); } } } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:local="clr-namespace:TestProject" Width="800" Height="600" Title="Behavior<T> 클래스 : 마우스 왼쪽 버튼 컨텍스트 메뉴 지원 동작 사용하기" FontFamily="나눔고딕코딩" FontSize="16"> <Window.Resources> <local:TestContextMenu x:Key="TestContextMenuKey"> <MenuItem Header="Dock to Fill" Tag="FILL" /> <Separator /> <MenuItem Header="Dock to Side"> <MenuItem Header="Left" Tag="LEFT" /> <MenuItem Header="Top" Tag="TOP" /> <MenuItem Header="Right" Tag="RIGHT" /> <MenuItem Header="Bottom" Tag="BOTTOM" /> </MenuItem> </local:TestContextMenu> </Window.Resources> <i:Interaction.Behaviors> <local:MouseLeftButtonContextMenuSupportBehavior /> </i:Interaction.Behaviors> <Grid> <Button Name="button" Width="100" Height="30" Padding="5" ContextMenu="{DynamicResource TestContextMenuKey}" local:MouseLeftButtonContextMenuSupportBehavior.AllowMouseLeftMouseDown="True" Content="테스트" /> </Grid> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
using System.Windows; using System.Windows.Controls; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); this.button.Click += button_Click; // 실행되지 않는다. AddHandler(TestContextMenu.MenuItemClickEvent, new RoutedEventHandler(TestContextMenu_MenuItemClick)); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private #region 버튼 클릭시 처리하기 - button_Click(sender, e) /// <summary> /// 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("버튼을 클릭했습니다."); } #endregion #region 테스트 컨텍스트 메뉴 항목 클릭시 처리하기 - TestContextMenu_MenuItemClick(sender, e) /// <summary> /// 테스트 컨텍스트 메뉴 항목 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void TestContextMenu_MenuItemClick(object sender, RoutedEventArgs e) { MenuItem item = e.OriginalSource as MenuItem; MessageBox.Show("컨텍스트 메뉴를 클릭했습니다 : " + item.Header); } #endregion } } |