在WPF中弹出右键菜单时判断鼠标是否选中该项
和上篇在WPF的TreeView中實現右鍵選定一樣,這仍然是一個右鍵菜單的問題:
這個需求是在一個實現剪貼板的功能的時候遇到的:在彈出右鍵菜單時,如果菜單彈出位置在ListViewItem中時,我們認為這項已經被選中,可以使用剪貼板功能。
?
當菜單彈出位置在ListView的空白處時,我們一般認為沒有項被選中,此時是不應該使能剪貼板功能的。
?
但是這個時候,該項仍然是選中的。不能通過Item的IsSelected的屬性來區分這兩種情況。這樣,就需要我們加一個判斷鼠標是否在所選的節點上的函數。實現這個功能的方式有如下兩種:
方法1:響應ListView的PreviewMouseRightButtonDown事件,在其中判斷是否有節點被選中。還是直接上代碼吧:
??? bool isItemSelected = false;
??? private void ListView_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
??? {
??????? object item = GetElementFromPoint((ItemsControl)sender, e.GetPosition((ItemsControl)sender));
??????? isItemSelected = (item != null);
??? }
??? private object GetElementFromPoint(ItemsControl itemsControl, Point point)
??? {
??????? UIElement element = itemsControl.InputHitTest(point) as UIElement;
??????? while (element != null)
??????? {
??????????? if (element == itemsControl)
??????????????? return null;
??????????? object item = itemsControl.ItemContainerGenerator.ItemFromContainer(element);
??????????? if (!item.Equals(DependencyProperty.UnsetValue))
??????????????? return item;
??????????? element = (UIElement)VisualTreeHelper.GetParent(element);
??????? }
??????? return null;
??? }
這個其實就是一個命中測試的方面的問題,代碼還是比較基礎的,也沒有什么需要解釋的地方,但寫起來還是有點麻煩。
方法2:同時響應ListView的PreviewMouseRightButtonDown事件和TreeViewItem的PreviewMouseRightButtonDown事件。
因此,只要在ListView_MouseDown 中設置isItemSelected = false,在ListViewItem_MouseDown中設置isItemSelected = true即可。由于非常簡單,就不附代碼了。
使用上面的兩種方法后,就可以直接在剪切復制命令的CanExecute函數中通過isItemSelected來判斷是否該使能剪切復制命令了。
另外,這兩方法是針對ItemsControl類型的控件的,也就是說,在TreeView或ListBox等控件中也可以使用,如果把它們封裝一下就更方便了。
總結
以上是生活随笔為你收集整理的在WPF中弹出右键菜单时判断鼠标是否选中该项的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 心事一件件的了掉,希望一切都能恢复到正常
- 下一篇: .Net 4.0并行库实用性演练