2010-05-10 4 views
0

У меня есть структура меню и подменю в Silverlight, и я хочу, чтобы подменю исчезло, когда элемент родительского меню теряет фокус - стандартное поведение в меню. Я заметил, что события щелчка подменю теряются при нажатии элемента подменю, потому что элемент родительского меню теряет фокус, и подменю исчезает.Кнопка Click Event Getting Lost

Это проще объяснить с кодом:

 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 никогда не запускается.

я предпочел бы избежать того, чтобы скрыть суб-меню каждый раз, но я немного удивлен тем, что замковое событие никогда не срабатывает в результате ...

я не могу поставить любые проверки внутри события LostFocus(), чтобы убедиться, что мой SubMenuBtn имеет фокус, потому что он не фокусируется до тех пор, пока не вызывается событие LostFocus(). Другими словами, SubMenuBtn.IsFocused = false при запуске функции LostFocus().

У кого-нибудь есть мысли по этому поводу?

ответ

0

Я нашел решение - хотя это не так просто или элегантно, как мне бы хотелось. Решение заключается в использовании вторичного потока, который приостанавливается только на мгновение перед выполнением.

ie.

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; 
    } 
}