윈폼에서는 IndexFromPoint 메서드를 통해 클릭이벤트가 발생된 커서 위치의 ListBoxItem의 Index를 쉽게 가져올 수 있었지만 wpf에서는 직접 알아내야 한다.
일단 Context Munu를 만들어야한다.
ContextMenu contextMenu = new ContextMenu();
MenuItem menuItemRename = new MenuItem();
menuItemRename.Header = "이름 바꾸기";
contextMenu.Items.Add(menuItemRename);
MenuItem menuItemDelete = new MenuItem();
menuItemDelete.Header = "삭제";
contextMenu.Items.Add(menuItemDelete);
wpf의 ListBox는 MouseDown이벤트가 작동이 안되므로 PreviewMouseRightButtonDown이벤트나 MouseRightButtonUp이벤트를 사용해야한다.
방법1. ListBox의 아이템들을 for문으로 돌려서 현재 마우스위치와 일치하는 아이템의 index를 찾아낸다.
private void listBox_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
int index = -1;
for (int i = 0; i < listBox.Items.Count; i++)
{
ListBoxItem listBoxItem = listBox.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
if (listBoxItem == null) continue;
Rect bounds = VisualTreeHelper.GetDescendantBounds(listBoxItem);
if (bounds.Contains(e.GetPosition(listBoxItem)))
{
index = i;
break;
}
}
if (index == -1) { return; }
//여기에 필요한 작업을 한다.
listBox.SelectedItem = listBox.Items.GetItemAt(index); //해당 index의 아이템을 선택한다.
contextMenu.IsOpen = true; //contextMenu를 보인다.
}
방법2. InputHitTest메서드를 이용해 우클릭된 위치의 ListBoxItem의 정보를 FrameworkElement로 가져와 다시 ListBoxItem으로 변환한다.
private void listBox_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = listBox.InputHitTest(e.GetPosition(listBox)) as FrameworkElement;
if (element.DataContext == null) { return; }
ListBoxItem listBoxItem = listBox.ItemContainerGenerator.ContainerFromItem(element.DataContext) as ListBoxItem;
//여기에 필요한 작업을 한다.
int index = listBox.ItemContainerGenerator.IndexFromContainer(listBoxItem); //index가 알고싶다면 이렇게
listBoxItem.IsSelected = true; //index를 알 필요없이 간편하게 아이템을 선택할 수 있다.
contextMenu.IsOpen = true; //contextMenu를 보인다.
}
wpf에서는 contextMenu.IsOpen = true; 로 마우스커서좌표를 확인할 필요없이 현재 마우스 좌표에 contextMenu가 나타났다.
그 점은 윈폼보다 편리하다.
'프로그램 개발 > 코딩자료' 카테고리의 다른 글
티스토리 스킨 문제로 애드센스 광고의 사이즈(반응형)가 표시되는 문제 (1) | 2024.08.11 |
---|---|
c# 실행파일의 폴더경로 (1) | 2022.09.04 |
[C] 비주얼스튜디오에서 stdio.h 에러 (1) | 2022.04.20 |
[WF] 윈폼프로젝트 폼 숨긴채 실행하기 (0) | 2022.04.12 |
[C#] 어셈블리 정보 작성은 어떻게 해야할까 (0) | 2022.04.10 |