Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376

Куча суб-окон. Как закрывать их глобально. Одной кнопкой

08.01.2025, 15:43. Показов 2761. Ответов 50
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем,
подскажите как технично закрыть все суб-окна одной кнопкой?

По отдельности закрываю в Сode Behind соответствующего суб-окна таким образом:


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
  private void OK_btn_Click(object sender, RoutedEventArgs e)
        {
 
            if  (((SubWindow35_VM) DataContext).SubWindow_isOpened)
            {
 
                this.Close(false);
 
                Settings.Default.Save(); 
 
               
            }
        }
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.01.2025, 15:43
Ответы с готовыми решениями:

Подправить RewriteRule для (суб)домена дабы работал глобально
Всем привет. Возьмем за пример домен - example.com и субдомен - privatbank.example.com Структура папок сайта -...

Как открывать/закрывать NavigationDrawer кнопкой "Menu"
собсно и вопрос в этом, где и что повесить на хардварную кнопку меню чтоб вызывался NavigationDrawer?

Как добавить несколько файлов одной кнопкой и в одной форме php
Здравствуйте! Как добавить несколько файлов одной кнопкой и в одной форме php Например есть такая форма: <form method='POST'...

50
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
09.01.2025, 20:45  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Wolfdp Посмотреть сообщение
Я вам в самом начале предложил самый элементарный способ через event. Можно не event, а хранить набор открытых окон. ООП и всё такое. Вроде должны знать если используете WPF, причем с DataContext и прочими приколами.
Ваш "элементарный" (идея) близок к моей "элементарщине" по духу. Посмотрю, возможно ли встроить.
Для меня не проблема delegate, event, подписаться.
Еще раз повторюсь, проблема - гонять это между VM-мами или VM и СB. И чтобы при этом Элд Хасп, не сильно ругался.

Добавлено через 25 минут
Wolfdp, сделал трассировку вашего примера.
В самом конце вопрос.
не увидел в каком месте оба ваших суб-окна подписаны на событие CloseAll?.Invoke(); ?
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
09.01.2025, 20:55
Цитата Сообщение от Berendom Посмотреть сообщение
Еще раз повторюсь, проблема - гонять это между VM-мами или VM и СB.
Для упрощение передачи параметров в конструктор используют ioc-контейнер, без него в любом случае нужно гонять некий объем параметров. Причем порой тянешь через десять классов значение, которое нужно только в одном случае в одном конкретном классе.

И честно говоря, тот факт что нужно тянуть -- не проблема. Фигня в том, что обычно это подразумевает жесткую зависимость, и чем дальше живет и развивается проект, тем больнее всё это сопровождать.

Цитата Сообщение от Berendom Посмотреть сообщение
И чтобы при этом Элд Хасп, не сильно ругался.
Такое имело бы смысл, будь Элд Хасп тимлидом на вашем проекте. А так вы вполне можете взять за основу менее правильный вариант и двигаться с ним. Либо сесть и разобраться с тем же DI, как рекомендовал Andrey-MSK. И если уж очень хочеться максимально кошерного подхода, то ваша модель не должна знать о существовании окна, и должна иметь свойство на которое окно подпишется для закрытия (по идеи через DataTrigger).

В этом случае можно не вводить никакие сервисы и наблюдателей, а просто передавать ссылку на общую модель в окна.

Добавлено через 1 минуту
Цитата Сообщение от Berendom Посмотреть сообщение
не увидел в каком месте оба ваших суб-окна подписаны на событие CloseAll?.Invoke(); ?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
internal class ShowCommand(GroupWindowWatcher watcher, Func<Window> windowFactory) : ICommand
{
    private Window? current;
 
    public event EventHandler? CanExecuteChanged;
 
    public bool CanExecute(object? parameter)
        => true;
 
    public void Execute(object? parameter)
    {
        if (current is null)
        {
            var window = windowFactory();
            watcher.CloseAll += window.Close; // подписываюсь на событие "закрыть все окна"
            current = window;
            window.Closed += (_, __) =>
            {
                current = null;
                watcher.CloseAll -= window.Close;
            };
            window.Show();
        }
        else
        {
            if(current.WindowState == WindowState.Minimized)
                current.WindowState = WindowState.Normal;
            current.Activate();
        }
    }
}
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
09.01.2025, 20:57  [ТС]
вижу.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
09.01.2025, 20:59
P.S. насчет подхода через общий event -- есть подозрение что при оперировании с модальными окнами очень легко наткнуться на дедлок: пинаем общее закрытие с модального окна, ждем отработки подписчиков, а там первый делегат -- главное заблокированное окно, которое ждет пока закроется модальное.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
09.01.2025, 21:03  [ТС]
Wolfdp,

опять же, у меня другие суб-окна, по другому вызываются, по другому закрываются.
Я бы не поленился каждое подписать на event. Как перегнать это все из VM в VM или CB?


Code
1
2
3
4
5
Для начала Одно окно закрыть Кнопкой в главном окне.
Например через Command подымается метод СloseAllMessages() в VM главного окна.
В данном методе я
-либо вижу VM суб-окна и присваиваю свойству IsOpen== false и оно закрыватеся.
-либо вижу в СB суб-окна метод Close(), который также закрывате суб-окно.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
09.01.2025, 21:11
Цитата Сообщение от Berendom Посмотреть сообщение
опять же, у меня другие суб-окна
скиньте пример, что у вас там за суб-окна такие.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
09.01.2025, 21:45  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
скиньте пример, что у вас там за суб-окна такие.
они не мои, изначальный разработчик App, тоже где-то стащил. Собственно как и мы все.
Посмотрю сейчас есть ли минимальный пример с ними.

Добавлено через 14 минут
Я конечно пример создам. Но пока вот:
Открывам так:

C#
1
DataWindow1 datawindow1 = new DataWindow1 { IsModal = false, AllowMove = true, IsOpen = false }; //  экземпляр

Mетод:

C#
1
OpenSubWindow(info.DataWindow1_popup, false, datawindow1); // здесь слева направо: Если DataWindow_popup == false, подымаем экземпляр суб-окна datawindow1
Комменты мои. Не верьте им, могу ошибиться.
Как закрыть экземпляр?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
09.01.2025, 21:50
Цитата Сообщение от Berendom Посмотреть сообщение
Лучше скажите как технично увидеть event созданный в VM основного окна в СB cуб-окна?
Немного общих рассуждений.
"Суб" подразумевает подчинённость. Раз есть подчинённость, то "хозяин" может либо сам управлять субами (закрыть их), либо передать в него контейнер являющийся инициатором управления (закрытия).

Варианты реализации:
1) Одна основная VM, по событию которой надо закрыть все субы. Субы сами решают, что они субы.
В этом случае экземпляр mainVM в ресурсах App, субы получают его оттуда и подписываются на нужное событие;

2) Есть множество Окон и у каждого множество своих субов. Как взаимодействует Окно с VM не важно, нужен только механизм управления "своими" субами. Здесь самый простой вариант - это в каждом окне иметь коллекцию своих субов. При открытии суба - экземпляр автоматически записывается в эту коллекцию. При необходимости управления своими субами - оно обращается к коллекции. В субах прописывается логика самоудаления из коллекции при закрытии.
Если для установления связи с рордителем используется Owner, то получить всех детей в родителе можно из OwnedWindows .

3) Есть множество Окон и у каждого множество своих субов. Каждый суб должен управляться состоянием VM Окна, но не задействуя само Окно. Здесь самое логичное передать VM в суб при его создании. Можно в конструкторе, можно и в ресурсах суба.


Это три основных варианта пришедших в голову.
1
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
09.01.2025, 22:22
Цитата Сообщение от Berendom Посмотреть сообщение
Но пока вот
Вы используете какую-то либу? Просто DataWindow и OpenSubWindow -- не дефолтные вещи для WPF.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
09.01.2025, 23:21  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
Вы используете какую-то либу? Просто DataWindow и OpenSubWindow -- не дефолтные вещи для WPF.
да, не дефолтные. Но к либе отношения не имеют.

По library: по моему один из ранних релизов. Т.к. App что у нас, уже лет как пять.

https://github.com/punker76/Ma... hildWindow
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
09.01.2025, 23:40
Цитата Сообщение от Berendom Посмотреть сообщение
да, не дефолтные. Но к либе отношения не имеют.
По library: по моему один из ранних релизов.
Вы о MahApps.Metro.SimpleChildWindow?
Это же не Окна. Этот класс назвали так для "солидности".
Это ContentControl и DataContext он получает от вышестоящего элемента - чаще всего Окна.

Metro редко использую и плохо его знаю.
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
09.01.2025, 23:47  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это же не Окна.
Вполне себе, ничего так, суб-окна. Их у нас целых 35 штук.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
10.01.2025, 00:10
Цитата Сообщение от Berendom Посмотреть сообщение
да, не дефолтные. Но к либе отношения не имеют.
Ваши классы я так понимаю помечены атрибутом IncrediblySecretData?

Цитата Сообщение от Berendom Посмотреть сообщение
Т.к. App что у нас, уже лет как пять.
чего вы так за этот app вцепились...

Добавлено через 15 минут
Цитата Сообщение от Berendom Посмотреть сообщение
Вполне себе, ничего так, суб-окна.
C#
1
public class ChildWindow : ContentControl
Вообще ни разу не окна. Это внутренние элементы окна, которые подогнали чтобы они смахивали на окно, не более.

В целом чхать, логика ровно таже: создаем общего наблюдателя, пинаем Close, подписываемся на public event RoutedEventHandler ClosingFinished чтобы отписаться от общего ивента. Просто вы до этого написали какой-то свой класс для отображения, а теперь хотите через него провернуть всё это (с вероятностью 146% либо отказываться от его использования, либо рефакторить).
0
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
10.01.2025, 00:47  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
Просто вы до этого написали какой-то свой класс для отображения, а теперь хотите через него провернуть всё это (с вероятностью 146% либо отказываться от его использования, либо рефакторить).
Как его закрыть? Учитывая то, что я выложил в в #27.

C#
1
datawindow1.Close()
там есть, но выводит ошибку.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
10.01.2025, 02:17
В #27 вы выложили название класса и метода, которые что-то там делают. Без лицезрения кода я могу ответить только "надо смотреть".
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
10.01.2025, 09:04
Цитата Сообщение от Berendom Посмотреть сообщение
Вполне себе, ничего так, суб-окна. Их у нас целых 35 штук.
У Окон своя логика поведения, отличная от других UI элементов.
Поэтому ваши "суб-ОКНА" сбивают с толка.
В вашем случае это можно назвать Message Box на основе Content Control или хотя бы сразу уточнить, что это MahApps.Metro.SimpleChildWindow.

Если Метро не накосячили (а у них это частое явление), то SimpleChildWindow должен иметь в DataContext то же что и Окно (вы же их непосредственно в Окне открываете?).

Цитата Сообщение от Berendom Посмотреть сообщение
OK_btn_Click
А как вы их показываете? Как объявляете?
Покажите XAML и/или Code Behind относящийся к этому вопросу.

Возможно, в Метро можно как-то получить все SimpleChildWindow Окна, но не могу точно сказать - надо покопаться.
И смутно в памяти, что SimpleChildWindow можно открывать не только в Окне, но в любом его регионе (дочернем UI элементе). Если так то, скорее всего аккумулятора SimpleChildWindow не будет. И тогда, самое логичное, это сделать AP свойство-коллекцию для Окна, в которое будут скидываться все SimpleChildWindow при их открытии. И RoutedCommand которая закрывает все SimpleChildWindow из этого свойства.
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
10.01.2025, 10:36
Berendom, Разберитесь с DI - Dependency Injection. Там сложного ничего нет, но когда разберётесь создание приложений для WPF будет гораздо проще, да и не только в WPF, сервисы мощная и удобная штука, написал один раз и пользуйся в любом проекте.

Добавлено через 1 час 30 минут
Цитата Сообщение от wizard41 Посмотреть сообщение
VM по определению не может ничего закрывать.
Ну в принципе может, если немного по другому обрисовать
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Метод команды VM
private async Task SaveEditAsync(object obj)
{
    // Передаём команде объект
    // И если этот объект поддерживает интерфейс IClosable
    if (obj is IClosable window)
    {
        try
        {
            if (_windowService.ShowQuestionMessage("Сохранить данные?", "Запись данных"))
                await SaveONZFullAsync();
            else
                return;
 
            if (EditMode == true && FromONZList == false)
            {
                if (_windowService.ShowQuestionMessage("Отредактировать еще один ОНЗ?", "Выход"))
                {
                    // Манипулируем этим объектом, в данном случае вызываем метод Close()
                    window.Close();
 
                    var vm = _viewModelFactory.CreateViewModel<IONZSelectDialogVM>();
 
                    vm.Branch = Branch;
                    vm.NZWorkMode = false;
                    vm.CurrentEObject = CurrentEObject;
 
                    _windowService.ShowDialog(vm);
                }
                else
                {
                    window.Close();
                }
            }
            else if (EditMode == false && FromONZList == false)
            {
                if (_windowService.ShowQuestionMessage("Создать еще один ОНЗ?", "Выход"))
                {
                    window.Close();
 
                    var vm = _viewModelFactory.CreateViewModel<IONZCreateDialogVM>();
 
                    vm.Branch = Branch;
                    vm.NZWorkMode = false;
                    vm.CurrentEObject = CurrentEObject;
 
                    _windowService.ShowDialog(vm);
                }
                else
                {
                    window.Close();
                }
            }
            else if (EditMode == true && FromONZList == true)
            {
                window.Close();
            }
 
            SaveResult = true;
        }
        catch (Exception ex)
        {
            _windowService.ShowErrorMessage(ex.Message, "Ошибка");
        }
    }
}
XML
1
2
3
4
<!-- Привязка команды во View -->
<Button x:Name="btnAdd" Content="Сохранить" Margin="5" Width="80" Height="25"
        Command="{Binding SaveCommand}" 
        CommandParameter="{Binding ElementName=ONZWindow}"/>
C#
1
2
3
4
5
6
7
8
9
10
namespace Services.Interfaces
{
    /// <summary>
    /// Интерфейс для реализации закрытия окна по команде.
    /// </summary>
    public interface IClosable
    {
        void Close();
    }
}
И само окно, которое нужно обрабатывать
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System.Threading;
using System.Windows;
 
using Services.Interfaces;
using Services.Interfaces.WindowsVM;
 
namespace DBClient.Views.Windows
{
    /// <summary>
    /// Interaction logic for ONZEditWindow.xaml
    /// </summary>
    public partial class ONZEditWindow : Window, IClosable
    {
        public ONZEditWindow()
        {
            InitializeComponent();
        }
 
        private void ONZWindow_Loaded(object sender, RoutedEventArgs e)
        {
            IONZEditWindowVM vm = (IONZEditWindowVM)DataContext;
 
            vm.ViewContext = SynchronizationContext.Current;
        }
    }
}
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
10.01.2025, 10:57
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Ну в принципе может, если немного по другому обрисовать
Мысль интересная. Я бы сделал иначе:
- в интерфейсе добавил ивент "закройся"
- в code переопределил получение DataContext, чекал наличие интерфейса и подписывался.

Не типично, но в целом идея сохраняется -- VM ничего не знает про отображение.
1
-12 / 24 / 4
Регистрация: 22.06.2020
Сообщений: 376
10.01.2025, 11:00  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А как вы их показываете? Как объявляете?
Покажите XAML и/или Code Behind относящийся к этому вопросу.
Как закрывается суб-окно (само себя) я показал в #1. Больше там ничего нет.
Экземпляр, Вызов показаны в #27.

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

Там у экземпляра cуб-окна, что создается в СB главного окна (#27) есть метод Сlose(), тот же самый, что используется в CB суб-окна для закрывания себя любимого (#1).
Но в СB главного окна этот метод выдает ошибку.
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
10.01.2025, 11:13
Цитата Сообщение от Wolfdp Посмотреть сообщение
Я бы сделал иначе
Можно покрутить ваш вариант... Я свой сделал что бы окно закрывало само себя, в то время мне показалось что так будет оптимально
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.01.2025, 11:13

Как запустить нужную форму одной кнопкой при фокусе в одной из закладок
Здравствуйте! Возникла проблема, определения фокуса и запуска определённой формы при фокусе определённой закладки, то есть если фокус в...

VBA Excel Как при переходе из одной процедуры в другую закрывать процедуру с которой идет перенаправление
Здравствуйте. Я в программировании на VBA мало что знаю, поэтому пожалуйста, объясните как можно доходчивее. Ситуация следующаа: мне нужно...

Как инкрементировать и декрементировать одной кнопкой.
Всем привет, это опять я. Делаю ночник на тини13. Управляю аппаратным ШИМ. При включении можно выбрать как будет увеличиваться значение...

Установил IE 9 и после этого стало появляться куча окон
Всем привет, Короче дело в том что установил IE 9 по моему, и после этого стало появлятся куча окон(которые открываются с ошибкой), удалить...

3 последовательных действия одной кнопкой, как сделать?
Добрый вечер всем! Я только начал заниматься АВР контроллерами, раньше только повторял, чьи- то проекты, а теперь хочется самому...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru