Из-за чего свойство IsVisible всегда возвращает false (C# WPF)?

Ссылка скопирована
1 ответ

Сейчас ситуация такая: добавил в проект некоторое количество дополнительных окон. Открываю их с кнопок и хочу сделать проверку, чтобы они не открывались повторно, если уже открыты. Эта проверка даже генерируется сама с помощьюIntelliSense:

if (Window1.Visibility == Visibility.Visible || Window2.Visibility == Visibility.Visible || Window3.Visibility == Visibility.Visible) { return; // Если одно из окон календаря уже открыто, то ничего не делаем }

Сейчас ситуация такая: но не работает. Так как свойствоWindowName.IsVisibleПостоянно выдаётFalseПо вводным:, независимо от того, открыто окно или нет. Более того, принудительная записьWindowName.Visibility = Visibility.VisibleТоже возвращаетFalseПри проверкеif (WindowName.Visibility == Visibility.Visible)
Нужно понять: ну как так? Гугловские объяснение никак не помогли и я в тупике. Может есть какие-то нюансы при работе с этими свойствами видимости, до которых я неумный просто не могу допереть?

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Кирилл JS Ответ

В WPF свойство IsVisible может возвращать false, если окно ещё не было показано, было закрыто, находится в скрытом состоянии или вы проверяете не тот экземпляр окна. Частая ошибка: при каждом клике создаётся новый объект окна, а проверка IsVisible делается на свежем объекте, который, естественно, ещё не видим.

Пример неправильной логики:

var window = new MyWindow();
if (!window.IsVisible)
{
    window.Show();
}

var window = new MyWindow(); if (!window.IsVisible) { window.Show(); }

Здесь проверка бесполезна, потому что window только что создан. Нужно хранить ссылку на уже открытое окно:

private MyWindow? _myWindow;
 
private void OpenWindow_Click(object sender, RoutedEventArgs e)
{
    if (_myWindow == null || !_myWindow.IsVisible)
    {
        _myWindow = new MyWindow();
        _myWindow.Closed += (_, _) => _myWindow = null;
        _myWindow.Show();
    }
    else
    {
        _myWindow.Activate();
    }
}

private MyWindow? _myWindow; private void OpenWindow_Click(object sender, RoutedEventArgs e) { if (_myWindow == null || !_myWindow.IsVisible) { _myWindow = new MyWindow(); _myWindow.Closed += (_, _) => _myWindow = null; _myWindow.Show(); } else { _myWindow.Activate(); } }

Если нужно искать уже открытое окно среди всех окон приложения:

var window = Application.Current.Windows
    .OfType()
    .FirstOrDefault();
 
if (window == null)
{
    window = new MyWindow();
    window.Show();
}
else
{
    window.Activate();
}

var window = Application.Current.Windows .OfType() .FirstOrDefault(); if (window == null) { window = new MyWindow(); window.Show(); } else { window.Activate(); }

Также важно понимать разницу между Hide и Close. После Close окно нельзя нормально показать повторно тем же экземпляром, нужно создавать новый. После Hide можно снова вызвать Show, и IsVisible будет меняться.

Если у вас “дополнительные окна” генерируются кнопками, заведите для каждого типа окна отдельное поле или общий менеджер окон. Проверяйте не созданный новый объект, а существующий экземпляр. Тогда IsVisible будет вести себя ожидаемо: true для реально показанного окна и false для скрытого или ещё не открытого.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно