Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.08.2013, 18:23   #1
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
Вопрос Доступ к окнам откуда угодно [C#, WPF]

Только недавно начал изучать C#, WPF. Было много проблем, но они быстро решались. Но эту проблему на могу уже решить второй день. Вопрос, собственно, в заголовке: Как мне получить доступ к дочерним окнам из другого окна (не обязательно главного), например. К главному окну я обращаюсь так:

Код:
App.Current.MainWindow
А как наоборот? Как обратиться к дочернему окну? Я почти уверен, что ответ прост до невозможности и лежит на поверхности. Заранее спасибо.
pashka_dos вне форума Ответить с цитированием
Старый 05.08.2013, 19:30   #2
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

Самый простой, хотя и нежелательный, способ - завести статические переменные на все нужные окна, и при создании каждого из них заполнитть переменные ссылками на созданные окна.
Например:
Код:
class Window1
{
public Window1()
{
Windows.MainWindow = this;
}
}

static class Windows
{
public static Window1 MainWindow;
...
}
Ну это простейший вариант. Если окон определенного типа несколько, то так не прокатит.
Изобретатель велосипедов
Selestis вне форума Ответить с цитированием
Старый 05.08.2013, 22:14   #3
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
Вопрос

Цитата:
Сообщение от Selestis Посмотреть сообщение
Самый простой, хотя и нежелательный, способ - завести статические переменные на все нужные окна, и при создании каждого из них заполнитть переменные ссылками на созданные окна.
Например:
Код:
class Window1
{
public Window1()
{
Windows.MainWindow = this;
}
}

static class Windows
{
public static Window1 MainWindow;
...
}
Ну это простейший вариант. Если окон определенного типа несколько, то так не прокатит.
Спасибо за ответ. Есть еще варианты? Я слышал это можно сделать с помощью делегатов.
pashka_dos вне форума Ответить с цитированием
Старый 05.08.2013, 22:42   #4
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

Ну вариантов вообще не счесть) Что придёт в голову. Просто в большинстве случаев как раз-таки "доступ ко всему откуда угодно" - признак очень плохого дизайна.
Если каждое жалкое окошко будет иметь возможность при смене любой настройки козявить главную форму (например), то такой код очень быстро приведет к появлению фееричных багов.
Как правило, чем меньше объект позволяет делать со своей внутренней логикой - тем лучше.
Изобретатель велосипедов
Selestis вне форума Ответить с цитированием
Старый 05.08.2013, 23:11   #5
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
Вопрос

Цитата:
Сообщение от Selestis Посмотреть сообщение
Ну вариантов вообще не счесть) Что придёт в голову. Просто в большинстве случаев как раз-таки "доступ ко всему откуда угодно" - признак очень плохого дизайна.
Если каждое жалкое окошко будет иметь возможность при смене любой настройки козявить главную форму (например), то такой код очень быстро приведет к появлению фееричных багов.
Как правило, чем меньше объект позволяет делать со своей внутренней логикой - тем лучше.
Я, наверное, неправильно выразился) поясню задачу: допустим при нажатии на кнопку на форме Child1, поменять цвет фона на форме Child2 (обе дочерние) так вот, как мне сделать красиво, не нарушая инкапсуляции, и других принципов ООП? Если можно, пример кода, спасибо.
pashka_dos вне форума Ответить с цитированием
Старый 06.08.2013, 00:24   #6
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

Как вариант:
делаете интерфейс
Код:
interface IColorChanger
{
event Action<Color> ColorChange;
}
пусть форма Child1 его реализует (т.е. там есть такое событие, и оно вызывается при нажатии на кнопку в ней, в параметры идёт цвет.
Код:
class Child1 : IColorChanger
{
event Action<Color> IColorChanger.ColorChange; //реализация интерфейса
...
private void someButtonClick(...)
{
if (ColorChange != null)
{
ColorChange(Color.Black);
}
}
}
Пусть у другой формы будет перегруженный конструктор:
Код:
class Child2
{
public Child2()
{
//этот конструктор только чтобы работал дизайней форм
}

public Child2(IColorChanger colorChanger)
{
colorChanger.ColorChanged += processColorChanged;
//подписываемся на событие изменения цвета. тут мы не знаем что нам дали форму Child1 - лишь интерфейс, позволяющий узнать о смене цвета
}

private void processColorChanged(Color color)
{
//наш обработчик, который среагирует на смену цвета
BackgroundColor = color;
}
}

class MainForm
{
void do()//некий метод, где создаются дочерние окна
{
var frm1 = new Child1();
var frm2 = new Child2((IColorChanger)frm1);//передаем форме объект для подписки на событие
...
}
}
Разумеется, это только один из вариантов, с использованием механизма событий.

В принципе, если говорить о
Цитата:
не нарушая инкапсуляции, и других принципов ООП
то, если считать нарушением инкапсуляции вызов одной формой метода другой формы, то получается несуразица - типа нельзя тогда вообще ничего явно вызывать ;-)
Главное чтобы просто ответственный за действие был один. Ну или механизм событий, как выше.

Менее труЪ-вариант:
Код:
class Child2 : Form
{
//тут метод смены цвета публичный. это вполне нормально, если смена цвета является прямым функционалом этой формы, а не реакцией на глобальное измеенние состояния программы (в таком случае я бы выбрал предыдущий вариант)
public void ChangeColor(Color color)
{
BackgroundColor = color;
}
}

class MainForm
{
private Child2 _frm2;

void do()//некий метод, где создаются дочерние окна
{
var frm1 = new Child1(processColorChanged);
_frm2 = new Child2();
}

private void processColorChanged(Color color)//делегат со ссылкой на этот метод передался другой форме в конструкторе (выше). она его вызовет и инициирует смену цвета, явно производимую здесь
{
_frm2.ChangeColor(color);
}

}

class Child1 : Form
{
private readonly Action<Color> _colorChangeCallback;
public Child1(){}

public Child1(Action<Color> colorChangeCallback)
{
_colorChangeCallback = colorChangeCallback;
}

private void someButtonClick(...)
{
colorChangeCallback(Color.Black);
}
}
Тут по-прежнему ни одна из дочерних форм не знает о другой, однако присутствует явный вызов метода дочерней формы из главной, таким образом она становится чем-то вроде управляющего элемента.

Ну и напоследок: писать в соответствии с принципами ООП не стоит делать самоцелью. Если вы можете эффективно решать задачу, не следуя им, то и не надо. А вот если вы поняли, что эти принципы реально облегчают вам процесс разработки/поддержки/доработки вашей программы, то тогда флаг в руки.
Изобретатель велосипедов

Последний раз редактировалось Selestis; 06.08.2013 в 00:27.
Selestis вне форума Ответить с цитированием
Старый 06.08.2013, 16:30   #7
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
По умолчанию

Selestis, спасибо Вам за развернутые ответы, плюсую))
pashka_dos вне форума Ответить с цитированием
Старый 06.08.2013, 18:28   #8
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

А в сторону PRISM и в частности EventAggregator посмотреть нет желания?
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[C# + WPF] Отлов нажатий клавиш, хуки, горячие клавиши в проекте WPF Casper-SC WPF, UWP, WinRT, XAML 3 03.03.2017 15:00
Доступ к окнам из другого класса Стремящийся Win Api 18 01.09.2012 22:47
Доступ к TextBox в WPF из другого класса CoderWPF WPF, UWP, WinRT, XAML 2 15.03.2012 11:07
Сколь угодно большое целое число 1nd1g0k1d Общие вопросы C/C++ 3 29.02.2008 18:15