按钮单击事件迷失

时间:2010-05-10 14:50:25

标签: silverlight events button click

我在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。

有人对此有任何想法吗?

1 个答案:

答案 0 :(得分: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;
    }
}