最近項(xiàng)目開(kāi)發(fā)過(guò)程中遇到了一個(gè)問(wèn)題,自己用ContextMenu創(chuàng)建了右鍵菜單后,彈出的右鍵菜單,不管是左擊還是右擊都是有效的,這顯然不符合人們的使用習(xí)慣,查了很久的資料,終于解決了這個(gè)問(wèn)題。話不多說(shuō),直接上核心部分代碼。
public bool IsMouseLeftButtonDown =false; //判斷鼠標(biāo)是否按下的標(biāo)志private static ContextMenu CreatContextMenu_ForNormalButton(uint controlId){ //創(chuàng)建一個(gè)右鍵菜單 ContextMenu contextMenu = new ContextMenu() { Name = "contextMenu" }; //將右鍵菜單進(jìn)行綁定 setContextMenu(contextMenu); //創(chuàng)建子菜單項(xiàng) MenuItem TestItem = new MenuItem() { Name = "MouseLeftButtonDownValid" }; TestItem.SetResourceReference(MenuItem.HeaderProperty, "Str_MouseLeftButtonDownValid"); TestItem.CommandParameter = string.Format("{0}:0x{1:X8}", MouseLeftButtonDownValid,controlId); TestItem.Command = MyRelayCommand; /*注意 這里為子菜單項(xiàng)添加鼠標(biāo)右鍵按下事件,一定是PreviewMouseDown,mouseDown不能進(jìn)入到MenuItem_MouseDown函數(shù),至于為什么要這樣,文章后面有說(shuō)明*/ TestItem.PreviewMouseDown += new MouseButtonEventHandler(MenuItem_MouseDown); //TestItem.MouseDown += new MouseButtonEventHandler(MenuItem_MouseDown); //將子菜單項(xiàng)添加到右鍵菜單中 contextMenu.Items.Add(TestItem); return contextMenu;}//綁定右鍵菜單private static void setContextMenu(ContextMenu menu){ Binding bind = new Binding(); bind.RelativeSource = new RelativeSource(RelativeSourceMode.Self); bind.Path = new System.Windows.PropertyPath("PlacementTarget"); menu.SetBinding(ContextMenu.DataContextProperty, bind);}//RelayCommand命令public RelayCommand MyRelayCommand{ get { if (null == this.operateDevice_RelayCommand) { this.operateDevice_RelayCommand = new RelayCommand(x => this.operateDevice(x), x => this.canOperateDevice(x)); } return this.operateDevice_RelayCommand; }}//鼠標(biāo)右鍵按下的判斷函數(shù)private static void MenuItem_MouseDown(object sender, MouseButtonEventArgs e){ if (e.LeftButton == MouseButtonState.Pressed) { IsMouseLeftButtonDown = true; //左鍵按下有效 } else { IsMouseLeftButtonDown = false; //右鍵按下無(wú)效 }}
然后通過(guò)IsMouseLeftButtonDown這個(gè)標(biāo)志去RelayCommand中的命令執(zhí)行函數(shù)operateDevice中去判斷操作是否可以執(zhí)行,便可以解決這個(gè)問(wèn)題。這里說(shuō)明PreviewMouseDown與MouseDown的區(qū)別:PreviewMouseDown 對(duì)應(yīng)的冒泡事件為 MouseDown 。兩者區(qū)別是,冒泡關(guān)系(或叫觸發(fā)的先后順序)。當(dāng)鼠標(biāo)按下,先觸發(fā)PreviewMouseDown,然后,阻止MouseDown的觸發(fā)(或叫阻止事件傳遞,或叫停止冒泡),所以可以將PreviewMouseDown視為MouseDown的過(guò)濾器(或叫必經(jīng)之路),通常你可以在PreviewMouseDown中做一些預(yù)先處理,為MouseDown做鋪墊?;蛘咦鲆恍┻壿嬇袛?,以決定是否要觸發(fā)MouseDown,等等之類,看你的需要而定。
希望對(duì)各位正在做C#前端開(kāi)發(fā)的同仁們有用。
參考文獻(xiàn):
聯(lián)系客服