2013-07-17 7 views
1

У меня есть окно, которое может иметь много экземпляров, открытых в одном приложении. Я отслеживаю их все в статическом словаре.Проблема: Активация другого окна при закрытом событии

Окно должно быть закрыто при нажатии escape, если окно активно. И если окно закрыто через escape, мне нужно активировать другое окно, которое хранится в словаре, если оно есть. Мне также нужно рассмотреть текущие z-порядок окна и активировать большинство из них, но на данный момент это не имеет значения.

Итак, когда у меня открыто несколько окон и попытайтесь их закрыть, нажав 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(); 
      } 
     } 
    } 
} 

Update # 1

Благодаря Potecaru Tudor, он нашел другое решение:

Решение, которое я нашел должен был set e.Handled = true в вашем KeyDown обработчик после вызова Close()

Решение Код:

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

Update # 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())); 
} 
... 

ответ

2

Я попытался воспроизвести вашу проблему без каких-либо успехов, окна закрываются только один за другим. Вы можете попробовать вызвать метод Close(), только если для свойства Window.IsActive установлено значение true.

EDIT Мне удалось воспроизвести вашу проблему.

Решение, которое я нашел в том, чтобы установить в обработчик KeyDown e.Handled = True после вызова Close()

Я полагаю, что вопрос заключается в том, что окна становятся активными один за другим перед первым один получает быть закрытыми, чтобы они также получили событие KeyDown. Странно, что это происходит только в моем примере для первых окон, которые вы открываете. После того, как вы их закрываете и начинаете открывать других, это не будет воспроизводиться.

+0

Пробовал мой образец проекта с проверкой «ea.Key == Key.Escape && IsActive» на клавише вниз, и он не помогает. Все окна все еще закрываются одновременно. – garek

+0

Вы правы. Точнее, вы правы дважды^__^ Во-первых, кажется, что «e.Handled = true» выполняет эту работу. И, во-вторых, это действительно странно и происходит только для открытых окон. – garek

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

Любые другие предложения будут оценены! Спасибо!

Смежные вопросы