Подтвердить что ты не робот

Как определить, является ли окно WPF модальным?

Какой самый простой способ выяснить, открывается ли окно модально или нет?

ПОЯСНЕНИЯ:

Я открываю окно вызова

myWindow.ShowDialog();

У меня есть нижний колонтитул с кнопками "ОК" и "Отмена", которые я хочу показать, только если окно открыто модально. Теперь я понимаю, что могу установить свойство, выполнив это:

myWindow.IsModal = true;
myWindow.ShowDialog();

Но я хочу, чтобы само окно приняло такое решение. Я хочу проверить в событии Loaded окна, является ли оно модальным.

ОБНОВИТЬ

Свойство IsModal фактически не существует в окне WPF. Это свойство, которое я создал. ShowDialog() блокирует текущий поток.

Я предполагаю, что могу определить, открывается ли окно с помощью ShowDialog(), проверяя, заблокирован ли текущий поток. Как бы я поступил так?

4b9b3361

Ответ 2

Там частное поле _showingAsDialog, когда окно WPF является модальным диалогом. Вы можете получить это значение через отражение и включить его в метод расширения:

public static bool IsModal(this Window window)
{
    return (bool)typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(window);
}

Значение устанавливается равным true, когда окно отображается как модальное (ShowDialog) и устанавливается на false после закрытия окна.

Ответ 3

Хорошо, так как моя последняя идея проголосовала, я доказал это. это работает - и я тестировал его в новом приложении WPF, поэтому я знаю, что он работает:

В моем основном окне (Window1) Loaded event я сделал:

Dim frm As New Window2
frm.ShowDialog()

В моем Window2 я затенял метод ShowDialog()

Private _IsModal As Boolean = False 'This will be changed in the IsModal method

Public Property IsModal() As Boolean
  Get
    Return _IsModal
  End Get
  Set(ByVal value As Boolean)
    _IsModal = value
  End Set
End Property

Public Shadows Sub ShowDialog()
  IsModal = True
  MyBase.ShowDialog()
End Sub

В моем загруженном событии я затем уволил окно сообщения, чтобы убедиться, что свойство IsModal изменено с False на True, и оно дает мне True, поэтому я знаю, что IsModal установлен. Затем MyBase.ShowDialog() заставляет базовый класс загружаться как модальный. Shadows позволяет нам переопределить поведение по умолчанию, даже если метод ShowDialog() не был объявлен как переопределяемый.

Пока он не "самостоятельно определяется", он не требует, чтобы вы передавали любое логическое значение извне и не требовали, чтобы вы устанавливали IsModal извне, он устанавливает его внутри себя, он доступен извне если вы так решили использовать его таким образом. Он устанавливает значение только в том случае, если оно загружено с помощью метода ShowDialog(), а не при использовании метода Show(). Я сомневаюсь, что вы найдете гораздо более простой способ сделать это.

Ответ 4

Вот фрагмент конвертера, который полезен для скрытия элементов, когда окно вызывается методом ShowDialog:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Window window = value as Window;
        if (window != null)
        {               
            var showingAsDialogFieldInfo = typeof(System.Windows.Window).GetField("_showingAsDialog",
                BindingFlags.NonPublic | BindingFlags.Instance);
            if ((bool) showingAsDialogFieldInfo.GetValue(window) == false)
            {
                return Visibility.Visible;
            }
        }
        return Visibility.Hidden;
    }

Ответ 5

модальное окно перестанет обрабатываться до тех пор, пока оно не будет закрыто.

В этом примере показано отображение немодального окна

dim f as myWindow
f.show
someOtherMethod()

В этом примере someOtherMethod запускается сразу после запуска окна.

В этом примере показано отображение модального:

dim f as myWindow
f.showDialog
someOtherMethod()

В этом примере someOtherMethod() не будет работать до тех пор, пока не вернется метод ShowDialog (это означает, что модальное окно было закрыто)

ИЗМЕНИТЬ из-за уточнения: Переопределите ShowDialog и перейдите в логическое.

dim f as MyWindow
f.ShowDialog(true)

затем в окне

Public Function Shadows ShowDialog(myVar as boolean) As Boolean
    if myVar then ShowButtons()
    return mybase.ShowDialog()
End Function 

Ответ 6

Используя UI Automation в Windows, я придумал что-то вроде этого:

void Window2_Loaded(object sender, RoutedEventArgs e)
{
    var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    var el = AutomationElement.FromHandle(hwnd);

    Object oPattern = null;

    if (el.TryGetCurrentPattern(WindowPattern.Pattern, out oPattern))
    {
        var pattern = oPattern as WindowPattern;

        this.Title = pattern.Current.IsModal.ToString();
    }
}

Но это кажется неработоспособным. Существует свойство IsModal http://msdn.microsoft.com/en-us/library/system.windows.automation.provider.iwindowprovider.ismodal.aspx должен быть правильный способ получить AutomationElement для окна и проверить, является ли его свойство IsModal истинным через Автоматизация.

Ответ 7

Вы также можете создать новый класс Dialog, который наследуется от Window. Создайте приватную переменную IsDialog в классе Dialog и переопределите функцию ShowDialog, используя new. Установите для переменной IsDialog значение true, когда вызывается ShowDialog:

public class Dialog : Window
{
    private bool IsDialog;

    new public bool? ShowDialog()
    {
        IsDialog = true;
        return base.ShowDialog();
    }
}

Ответ 8

Можно ли проверить родительское окно окна, чтобы узнать, отключен ли он? Я не уверен, что это можно сделать с помощью API-интерфейсов WPF или нет, но если вы еще ничего не получили HWND из окна WPF, получите его родителя через Win32 P/Invoke (или что-то еще), а затем проверьте, отключен или нет.

Определенно не чистый метод, но кажется, что он может работать.

Ответ 9

Window не позволяет вам установить значение для Window.DialogResult, если окно не было открыто с помощью ShowDialog(). Следовательно, вы можете попытаться установить Window.DialogResult и посмотреть, генерирует ли он исключение.