1

我有一些窗口,可以在单个应用程序中打开许多实例。我在静态字典中跟踪所有这些。

如果窗口处于活动状态,则必须在escape按下时关闭窗口。如果窗口关闭,escape我需要激活其他窗口,如果有的话,存储在字典中。我还需要考虑当前的窗口 z-order 并激活其中的大部分,但现在这并不重要。

所以,当我打开一些窗口并尝试关闭它们时escape,我得到的是在某个时刻所有剩下的窗口都同时关闭。

这是代码示例:

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private int _count;

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Window1.Run(this, ++_count);
        }
    }

    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private static Dictionary<int, Window1>  _opened = 
            new Dictionary<int, Window1>();

        private int _key;

        public Window1()
        {
            InitializeComponent();

            KeyDown += OnKeyDown;
        }

        private void OnKeyDown(object sender, KeyEventArgs ea)
        {
            if (ea.Key == Key.Escape)
            {
                Close();
            }
        }

        public static void Run(Window owner, int key)
        {
            Window1 w = null;

            if (_opened.TryGetValue(key, out w))
            {
                w.Activate();
            }
            else
            {
                w = new Window1{_key = key};
                w.Closed += (s, e) =>
                    {
                        var win = s as Window1;

                        _opened.Remove(win._key);
                        if (_opened.Count > 0)
                        {
                            _opened.First().Value.Activate();
                        }
                    };
                _opened.Add(key, w);
                w.Show();
            }
        }
    }
}

更新#1

感谢Potecaru Tudor,他找到了另一个解决方案:

我找到的解决方案是在调用 Close() 后在 KeyDown 处理程序中设置 e.Handled = true

解决方案代码:

private void OnKeyDown(object sender, KeyEventArgs ea)
{
    if (ea.Key == Key.Escape)
    {
        ea.Handled = true;
        Close();
    }
}

更新#2

这是另一个不太优雅的解决方案,仅供记录

...
_opened.Remove(win._key);
if (_opened.Count > 0)
{
    // i suppose here is the error hidden
    var w2 = _opened.First().Value;
    w2.Dispatcher.BeginInvoke(new Action(() => w2.Activate()));
}
...
4

2 回答 2

2

我试图重现您的问题,但没有成功,窗户正在一一关闭。仅当Window.IsActive属性设置为 true时,您才可以尝试调用 Close() 方法。

编辑我设法重现您的问题。

我找到的解决方案是在调用 Close() 后在 KeyDown 处理程序中设置e.Handled = true

我想问题是在第一个窗口关闭之前,窗口一个接一个地变为活动状态,因此它们也收到了 KeyDown 事件触发。奇怪的是,它只发生在我打开的第一个窗口的示例中。在您关闭所有这些并开始打开其他之后,这将不会重现。

于 2013-07-17T12:09:23.083 回答
0

我发现的唯一方法是延迟下一个窗口激活,如下所示:

    ...
    _opened.Remove(win._key);
    if (_opened.Count > 0)
    {
        // i suppose here is the error hidden
        var w2 = _opened.First().Value;
        w2.Dispatcher.BeginInvoke(new Action(() => w2.Activate()));
    }
    ...

任何其他建议将不胜感激!谢谢!

于 2013-07-17T10:04:29.033 回答