![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| _Dream |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 133 Регистрация: 4.11.2006 Где: Там Репутация: нет Всего: нет |
читал тут и тут
не понял как мне разрулить ситуацию(из-за чего и был выбран этот паттерн) у меня есть форма на ней контрол на нем еще и т д и мне надо чтоб по нажатию кнопки на форме(самой внешней) было произведено некое действие на самом внутреннем контроле. как быть? --------------------
Noone dies a virgin. Life screws us all... |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
А причем здесь команда? Тут подходит цепочка обязанностей Только вот немного непонятно. Что будет если этих "самых внутренних" будет больше одного. Кто должен получить запрос? (в обратном порядке все нормально получается) Пример:
P.S. Код, определяющий принадлежность класса интерфейсу (control is IMessageHandler), требует большого количества процессорного времени, так что если передача сообщений будет частой есть смысл хранить коллекцию контролов, которые реализуют IMessageHandler и наполнять ее по мере добавления контролов в коллекцию Controls Добавлено через 2 минуты и 31 секунду P.P.S. В моем случае запрос будет обработан !всеми! контролами, у которых в коллекции нет дочерних контролов-обработчиков Это сообщение отредактировал(а) ivashkanet - 16.5.2007, 09:09 |
|||
|
||||
| tol05 |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
ИМХО это не есть оптимальный вариант
зачем нам по каждому чиху проходить по всей коллекции контролов? Т.е. пришло, напр. событие MouseMove, и мы 100 контролов опрашиваем, один нашли. пришло MouseClick, оказалось, вообще ни один не подписан, самим надо обрабатывать. А мы всех по очереди подергали уже. Если у нас 50-100 контролов и 20 событий, то сколько комбинаций получиться? Предлагаю: в классе формы объявить делегат (или событие), на которое подписываются внутренние контролы. На все внешние события подписаться формой и когда форма отловит событие - дергать наш делегат(событие). Кто подписан, тот и получит. Допустим, есть форма form1 и три кнопки button1, button2, button3
все, когда форма получит событие, она вызовет зарегистрированный обработчик внутреннего контрола. Если обработчиков событий формы мы не регистрировали, то только внутренний контрол и обработает. К тому же, никакого лишнего кода по проверке делегата на null. Пользуемся концентрированным опытом мелкомягких. З.Ы. Да, отжег я здоровски. Для того, чтобы получилось то, что я написал, нужно создать свой класс, наследник Button и button1, button2, button3 сделать его экземплярами... Определить в них эти обработчики. ну, тогда подписаться формой на все события, и в них вызывать, события стандартных Button, например,
Это сообщение отредактировал(а) tol05 - 16.5.2007, 09:40 -------------------- На хорошей работе и сны хорошие снятся. |
||||
|
|||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Во-прервых, не по каждому чиху, а только при запуске HandleMessage() Во-вторых, я уже об этом упомянул В-третьих, если создать свою личную "коллекцию контролов, которые реализуют IMessageHandler и наполнять ее...", то скорость вызова будет ничуть не меньше, чем при событиях. В-четвертых, класс выбрасывающий событие НЕ ДОЛЖЕН интересоваться кто получил сообщение о событии и вообще получил ли кто-то его. В твоем же случае, нужно смотреть зарегистрированы ли обработчики на событие. Добавлено через 1 минуту и 44 секунды
А без наследования никак |
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
ivashkanet,
я как раз это и имел в виду. По каждому запуску HandleMessage() на панели, она будет опрашивать ВСЕ свои контролы.
вот с этим я как раз полностью согласен. -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
И все-таки мне что-то не нравится. Что если нужно, чтобы сообщение обработалось только частью вложенных элементов? Или и вложенными, и контейнерами? Предлагаю дополнить твой код, ivashkanet
Это сообщение отредактировал(а) tol05 - 16.5.2007, 11:08 -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| _Dream |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 133 Регистрация: 4.11.2006 Где: Там Репутация: нет Всего: нет |
спасибо за помощь.. решено сделать так..
есть некий класс КомандМэнеджер, который реализует интерфейс ИКомандМэнеджер(в интерфейсе методы адд,дел) в этом же классе есть свойство возвращающее наш контрол самого нижнего уровня. КомандМэнеджер интернал и лежит рядом с контролом_нижнего_уровня. у самого контрола есть свойство возвращающее ИКомандМэнеджер. и просто вытягиваем наверх наш обьект КомандМэнеджер(до уровня верхей формы) и все.. ну и все это через интерфейс.. --------------------
Noone dies a virgin. Life screws us all... |
|||
|
||||
| ivashkanet |
|
||||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Гы, у меня был такой вариант, но: 1) я счел его сложным и не стал его выкладывать 2) IMessageHandler это интерфейс, который реализуется, а не наследуется, так что эту бороду с коллекцией нужно нужно реализовывать в каждом классе 3) основная причина клиенту интерфейса побоку на эту коллекцию (ему о ней вообще знать не желательно, иначе наступит момент, когда ее заюзают, что неправильно), так что она должна быть приватная, чего не может обеспечить интерфейс. P.S. Пройдусь по твоему коду:
Его нельзя объявить приватным, так как это метод интерфейса (компилятор не простит). Если уж наружу выставлен эвент, то именно его и нужно было объявлять в интерфейсе. Клиент не обязан ничего знать о Панели и др. контролах, ему нужна только функциональность IMessageHandler Не хочу обидеть, но подписка и отписка на свой собственный эвент --- это круто. Вместо цикла в конструкторе лучше подписаться на два события класса Control: ControlAdded и ControlRemoved Кто вызывает этот приватный метод я так и не понял Добавлено через 4 минуты и 29 секунд Ничего не понял |
||||
|
|||||
| _Dream |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 133 Регистрация: 4.11.2006 Где: Там Репутация: нет Всего: нет |
если упростить то я тяну наверх контрол
--------------------
Noone dies a virgin. Life screws us all... |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
||||
|
||||
| _Dream |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 133 Регистрация: 4.11.2006 Где: Там Репутация: нет Всего: нет |
ну по событиям.
то есть у всех участников цепочки(кто тянет) реализован интерфейс(например с 1м полем) и при определенном условии(например я выбрал свой грид на контроле_нижнего_уровня) у меня срабатывает мое событие. на него подписан контрол_более_высокого_уроня. он получает данные от того кто зажег событие и это вызывает следуеще событие на еще 1 уровень вверх.. и таким образом я тяну данные на самый верх.. вроде это стандартный подход --------------------
Noone dies a virgin. Life screws us all... |
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
ivashkanet, да, согласен со всеми твоими упреками. Я в блокноте писал, так что
не проверял. действительно, лажа получилась HandleMessage делаем открытым, ProcessMessage ни фиг не нужен, пусть вызовом HandleMessage вызываются обработцики для текущего контрола и HandleMessage для вложенных ConsumeOnEvent не нужен, только внутри класса используется код сильно упростился
в принципе и Handlers в интерфейсе не нужен, но я оставил и сделал свойчтво доступа. Пусть будет Я не обижаюсь, когда мне указывают на мои ошибки и огрехи. Обижает, когда чел просто прикалывается беспонтово. Это сообщение отредактировал(а) tol05 - 16.5.2007, 12:03 -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
_Dream, вот теперь понятно, но заявлено было наоборот:
Т.е. была передача сообщения сверху вниз. _Dream, есть небольшой комментарий: механизм событий ненадежен. Что будет если кто-то забудет подписаться на это событие? Тогда оно просто уйдет вникуда. Через 3-4 месяца вы на эту ошибку будете с большими глазами смотреть. P.S. tol05, опять есть комментарии пот твоему коду Например, из HandleMessage и processMessage в интерфейсе кто-то лишний |
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
Никто не лишний
processMessage - для подписки обработчиков (хранения методов, что будут обработку проводить и их вызова). Если его из интерфейса убрать, то нет гарантии, что внутри нашего контрола будут контролы, которые могут подписываться. HandleMessage - для инициирования обработки и передачи управления вложенным контролам. Если его убрать, то как вложенные контролы получат сообщение? т.е. HandleMessage - для работы с сообщением по вертикали, а processMessage - по горизонтали (в рамках одного, текущего контрола) З.Ы. Другое дело, что consume явно не работает. Убрать его нафиг и вместо него все-таки
так правильнее будет, как не крути Это сообщение отредактировал(а) tol05 - 16.5.2007, 13:39 -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |