我在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 :(得分: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;
}
}