2010-05-10 82 views
0

我在Silverlight中有一個菜單和子菜單結構,並且當父菜單項失去焦點時我想讓子菜單消失 - 標準菜單行爲。我注意到當子菜單項被點擊時,子菜單的點擊事件丟失,因爲父菜單項失去焦點並且子菜單消失。按鈕單擊事件迷失

它很容易與代碼解釋:

 ParentMenuBtn.Click += delegate 
     { 
      SubMenu.Visibility = (SubMenu.Visibility == Visibility.Visible) ? SubMenu.Collapsed : SubMenu.Visible; 
     }; 
     ParentMenuBtn.LostFocus += delegate 
     { 
      SubMenu.Visibility = Visibility.Collapsed; 
     }; 
     SubMenuBtn.Click += delegate 
     { 
      throw new Exception("This will never be thrown."); 
     }; 

在我的例子,被點擊SubMenuBtn時,觸發第一個事件是ParentMenuBtn.LostFocus(),隱藏SubMenuBtn的容器。一旦容器的可見性崩潰,就不會觸發Click事件。

我寧願避免隱藏子菜單中的每個時間,但我有點驚訝,Click事件被觸發從來沒有作爲一個結果......

我不能把任何檢查在LostFocus()事件中查看SubMenuBtn是否具有焦點,因爲直到調用LostFocus()事件之後它才獲得焦點。換句話說,當LostFocus()被觸發時,SubMenuBtn.IsFocused = false。

任何人對此有任何想法?

回答

0

我已經找到了解決方案 - 儘管它並不像我所希望的那麼簡單或優雅。解決方案是使用輔助線程,在執行之前只暫停一會兒。

即。

public partial class Navigation : UserControl 
{ 
    public Navigation() 
    { 
     ParentMenuBtn.Click += delegate 
     { 
      SubMenu.Visibility = (SubMenu.Visibility == Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;  
     }; 
     ParentMenuBtn.LostFocus += delegate(object sender, RoutedEventArgs e) 
     { 
      HideSubMenu(SubMenu); 
     }; 
     SubMenuBtn.Click += delegate 
     { 
      //Sub Menu Button actions... 
     }; 

    private void HideSubMenu(UIElement subMenu) 
    { 
     //Get the Main Page 
     App app = (App)Application.Current; 
     MainPage mainPage = (MainPage)app.RootVisual; 

     Thread thread = new Thread(Navigation.HideSubMenu); 
     thread.Start(new ThreadState(mainPage, subMenu)); 
    } 

    private static void HideSubMenu(object threadStateObj) 
    { 
     ThreadState threadState = (ThreadState)threadStateObj; 
     //Execute after 5 milliseconds... 
     System.Threading.Thread.Sleep(5); 
     threadState.MainPage.Dispatcher.BeginInvoke(delegate() { 
      threadState.TargetElement.Visibility = Visibility.Collapsed; 
     }); 
    } 

我只是用所謂的ThreadState一個簡單的對象來處理所有的狀態對象我想保留:

public class ThreadState 
{ 
    public MainPage MainPage = null; 
    public UIElement TargetElement = null; 

    public ThreadState(MainPage mainPage, UIElement targetElement) 
    { 
     this.MainPage = mainPage; 
     this.TargetElement = targetElement; 
    } 
}