Событие нажатия кнопки становится потерянным - PullRequest
0 голосов
/ 10 мая 2010

У меня есть структура меню и подменю в 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 (). Другими словами, SubMenuBtn.IsFocused = false при срабатывании LostFocus ().

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

1 Ответ

0 голосов
/ 10 мая 2010

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

т.

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