Как я могу ссылаться на активное окно приложения WPF в С#, используя что-то вроде свойства ActiveForm в WinForms?
Обратитесь к активному окну в WPF?
Ответы (5)
Одним из возможных способов было бы просмотреть список открытых окон в приложении и проверить, какое из них имеет IsActive = true
:
Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
Не уверен, что может быть более одного активного окна, если, например, отображается модальное диалоговое окно, и в этом случае владелец диалогового окна и само диалоговое окно могут быть активны.
OfType<Window>()
вместо Cast<Window>()
на всякий случай...
- person Aviad P.; 20.06.2012
FirstOrDefault
вместо SingleOrDefault
, который выдает исключение, если есть несколько совпадающих элементов. Плюс это должно быть немного быстрее, потому что он принимает первый результат и не нужно проверять, что он единственный.
- person ygoe; 25.10.2013
FirstOrDefault
, и SingleOrDefault
возвращают null
, что означает отсутствие окон с IsActive как true. Как это возможно?
- person digitguy; 08.04.2014
Есть лучший способ сделать это с помощью PInvoke. Ответ Авиада не работает все время (есть некоторые крайние случаи с диалогами).
IntPtr active = GetActiveWindow();
ActiveWindow = Application.Current.Windows.OfType<Window>()
.SingleOrDefault(window => new WindowInteropHelper(window).Handle == active);
Сначала необходимо включить следующий импорт:
[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();
IsActive
. Использование другого решения вызвало исключение (SingleOrDefault
выдает, если есть более одного совпадения с предикатом) или не дало мне фактическое активное окно при использовании FirstOrDefault
- person clcto; 08.08.2014
Я знаю, что это немного старый вопрос, но я думаю, что мой ответ может кому-то помочь.
Моя проблема заключалась в следующем: у меня было приложение WPF MVVM, и мне нужно было получить мой экземпляр MainWindow
во втором представлении, то есть во второй модели представления, чтобы установить видимость кнопки строки заголовка на visible
.
Это мое решение:
MainWindow window = (MyApp.MainWindow)App.Current.MainWindow;
window.btnSearch.Visibility = System.Windows.Visibility.Visible;
Надеюсь, это поможет кому-то.
У меня проблемы с этим способом "Application.Current.Windows.OfType().SingleOrDefault(x => x.IsActive);" особенно потому, что я создавал приложение с главным окном, тогда у меня были проблемы при выборе главного окна. Я разрешаю это, создавая это:
В каком-то базовом классе или App.xaml.cs создайте это:
public static Window ActivatedWindow {get;set;}
Затем поместите свой базовый класс, производный от окна, или все события активации вашего окна:
Первый вариант — персональный базовый класс окна:
public class MetroToolWindowBase
{
public MetroToolWindowBase()
{
Activated += new EventHandler(MakeActive);
}
private void MakeActive(object sender, EventArgs e)
{
App.ActivatedWindow= this;
}
}
Второй вариант — в активированном событии Windows:
private void XWindow_Activated(object sender,EventArgs e)
{
App.ActivatedWindow= this;
}
принятый ответ работает, но я столкнулся с пограничным случаем при отладке в Visual Studio, о котором, возможно, стоит упомянуть.
Код:
var activeWindow = Application.Current?.Windows.OfType<Window>().FirstOrDefault(w => w.IsActive);
if (window != null)
{
window.Owner = activeWindow;
window.DataContext = viewModel;
}
Я заметил, что когда у меня была точка останова в другом классе, и я нажал F5, чтобы добраться до точки останова в приведенном выше коде, возвращенное activeWindow
было нулевым, и каким-то образом это привело к исчезновению моего диалогового окна.
Это можно решить с помощью следующего обходного пути:
#if DEBUG
if (activeWindow == null)
{
activeWindow = Application.Current?.MainWindow;
// Or just force Topmost = true
}
#endif
По крайней мере, я могу убедиться, что вижу всплывающее окно во время отладки.
Я провел еще несколько проб и ошибок и обнаружил, что эта проблема возникает, когда диалоговое окно имеет следующее свойство: ShowInTaskbar="False"
. Когда я установил для него значение true, диалоговое окно появилось даже с нулевым владельцем.
Другой обходной путь состоял в том, чтобы установить Topmost="True"
, тогда я также мог сохранить свое свойство ShowInTaskbar.
Я не знаю, что происходит, но если у кого-то есть больше информации об этом, я был бы очень признателен.