[C#] WPF에서 헤더를 마우스 오른쪽 버튼으로 클릭할 때 메뉴 변경
마우스 오른쪽 버튼 클릭 시 메뉴(컨텍스트 메뉴)
이런 메뉴를 컨텍스트 메뉴라고 합니다.
이번에는 자작 앱의 헤더 부분을 마우스 오른쪽 버튼으로 클릭했을 때 메뉴를 변경하는 방법을 설명합니다.
위 화면의 메뉴에 추가하는 패턴과 완전히 자작 메뉴를 표시하는 패턴의 두 가지를 만듭니다.
이런 느낌이 듭니다.
기존 컨텍스트 메뉴에 요소를 추가하는 방법
Win32API를 사용합니다.
우선 Win32API 사용할 수 있도록 하고 사용할 함수를 선언합니다.
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern bool InsertMenu(IntPtr hMenu, Int32 wPosition, Int32 wFlags, Int32 wIDNewItem,
string lpNewItem);
그런 다음 사용할 상수를 선언합니다.
private readonly Int32 MF_BYPOSITION = 0x400;
private readonly Int32 MF_SEPARATOR = 0x800;
private const Int32 ITEMONEID = 1000;
private const Int32 ITEMTWOID = 1001;
private readonly Int32 WM_SYSCOMMAND = 0x112;
로드시 처리를 작성합니다.
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
IntPtr windowhandle = new WindowInteropHelper(this).Handle;
HwndSource hwndSource = HwndSource.FromHwnd(windowhandle);
IntPtr systemMenuHandle = GetSystemMenu(windowhandle, false);
InsertMenu(systemMenuHandle,5, MF_BYPOSITION| MF_SEPARATOR, 0, string.Empty);
InsertMenu(systemMenuHandle,6, MF_BYPOSITION, ITEMONEID, "Item 1");
InsertMenu(systemMenuHandle,7, MF_BYPOSITION, ITEMTWOID, "Item 2");
hwndSource.AddHook(new HwndSourceHook(WndProc));
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
{
if(msg == WM_SYSCOMMAND)
{
switch(wparam.ToInt32())
{
case ITEMONEID:
{
MessageBox.Show("Item 1 was clicked");
handled = true;
break;
}
case ITEMTWOID:
{
MessageBox.Show("Item 2 was clicked");
handled = true;
break;
}
}
}
return IntPtr.Zero;
}
자체 제작 컨텍스트 메뉴를 표시하는 방법
xaml 측에 자원을 정의합니다.
우선, Item1 때만 구현.
<Window.Resources>
<ContextMenu x:Key="contextMenu" >
<MenuItem Header="Item 1" Click="MenuItem_OnClick"></MenuItem>
<MenuItem Header="Item 2"></MenuItem>
<MenuItem Header="Item 3"></MenuItem>
</ContextMenu>
</Window.Resources>
코드 비하인드 측
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
IntPtr windowhandle = new WindowInteropHelper(this).Handle;
HwndSource hwndSource = HwndSource.FromHwnd(windowhandle);
hwndSource.AddHook(new HwndSourceHook(WndProc));
}
private void MenuItem_OnClick(object sender, RoutedEventArgs e)
{
var item = sender as MenuItem;
MessageBox.Show(item.Header.ToString());
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
{
if(msg == 0xa4)
{
ShowContextMenu();
handled = true;
}
return IntPtr.Zero;
}
private void ShowContextMenu()
{
var contextMenu = Resources["contextMenu"] as ContextMenu;
contextMenu.IsOpen = true;
}
소스 코드
htps : // 기주 b. 코 m / こめ t / Wpf 이렇게 xt
Reference
이 문제에 관하여([C#] WPF에서 헤더를 마우스 오른쪽 버튼으로 클릭할 때 메뉴 변경), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/todu/items/a3d053f514a4fe36bf29
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern bool InsertMenu(IntPtr hMenu, Int32 wPosition, Int32 wFlags, Int32 wIDNewItem,
string lpNewItem);
private readonly Int32 MF_BYPOSITION = 0x400;
private readonly Int32 MF_SEPARATOR = 0x800;
private const Int32 ITEMONEID = 1000;
private const Int32 ITEMTWOID = 1001;
private readonly Int32 WM_SYSCOMMAND = 0x112;
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
IntPtr windowhandle = new WindowInteropHelper(this).Handle;
HwndSource hwndSource = HwndSource.FromHwnd(windowhandle);
IntPtr systemMenuHandle = GetSystemMenu(windowhandle, false);
InsertMenu(systemMenuHandle,5, MF_BYPOSITION| MF_SEPARATOR, 0, string.Empty);
InsertMenu(systemMenuHandle,6, MF_BYPOSITION, ITEMONEID, "Item 1");
InsertMenu(systemMenuHandle,7, MF_BYPOSITION, ITEMTWOID, "Item 2");
hwndSource.AddHook(new HwndSourceHook(WndProc));
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
{
if(msg == WM_SYSCOMMAND)
{
switch(wparam.ToInt32())
{
case ITEMONEID:
{
MessageBox.Show("Item 1 was clicked");
handled = true;
break;
}
case ITEMTWOID:
{
MessageBox.Show("Item 2 was clicked");
handled = true;
break;
}
}
}
return IntPtr.Zero;
}
xaml 측에 자원을 정의합니다.
우선, Item1 때만 구현.
<Window.Resources>
<ContextMenu x:Key="contextMenu" >
<MenuItem Header="Item 1" Click="MenuItem_OnClick"></MenuItem>
<MenuItem Header="Item 2"></MenuItem>
<MenuItem Header="Item 3"></MenuItem>
</ContextMenu>
</Window.Resources>
코드 비하인드 측
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
IntPtr windowhandle = new WindowInteropHelper(this).Handle;
HwndSource hwndSource = HwndSource.FromHwnd(windowhandle);
hwndSource.AddHook(new HwndSourceHook(WndProc));
}
private void MenuItem_OnClick(object sender, RoutedEventArgs e)
{
var item = sender as MenuItem;
MessageBox.Show(item.Header.ToString());
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
{
if(msg == 0xa4)
{
ShowContextMenu();
handled = true;
}
return IntPtr.Zero;
}
private void ShowContextMenu()
{
var contextMenu = Resources["contextMenu"] as ContextMenu;
contextMenu.IsOpen = true;
}
소스 코드
htps : // 기주 b. 코 m / こめ t / Wpf 이렇게 xt
Reference
이 문제에 관하여([C#] WPF에서 헤더를 마우스 오른쪽 버튼으로 클릭할 때 메뉴 변경), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/todu/items/a3d053f514a4fe36bf29텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)