Разработка пользовательского интерфейса на основе технологии Windows Presentation Foundation - страница 19

Шрифт
Интервал


Приведенные тексты методов показывают, что при смене обработчика недостаточно присоединить к событию новый обработчик; необходимо также отсоединить от события обработчик, ранее связанный с ним. Данное обстоятельство обусловлено тем важным фактом, что к одному и тому же событию можно последовательно присоединить несколько обработчиков (для этого достаточно применить к этому событию несколько раз оператор +=). Следует отметить, что данная возможность для событий визуальных компонентов применяется крайне редко (достаточно отметить, что с помощью окна Properties или xaml-файла присоединить к одному событию несколько обработчиков нельзя). В то же время при явном присоединении обработчиков эта особенность может приводить к появлению трудно выявляемых ошибок, если, например, один и тот же обработчик будет присоединен к событию несколько раз. Подобные проблемы можно проиллюстрировать с помощью нашей программы, если закомментировать заголовок оператора if в обработчике Canvas_MouseDown:

Если теперь после запуска программы несколько раз щелкнуть мышью на окне, а затем приручить кнопку button2, то при ее последующем нажатии окно несколько раз последовательно перейдет из развернутого состояния в стандартное и обратно. Это объясняется тем, что теперь каждый щелчок на окне присоединяет к событию Click кнопки button2 новый экземпляр обработчика button2_Click, и при нажатии на эту кнопку каждый экземпляр обработчика последовательно запускается на выполнение. Ситуация осложняется еще тем обстоятельством, что в программе невозможно выяснить, сколько и какие обработчики присоединены в настоящий момент к данному событию (а не зная этого, нельзя и обеспечить отсоединение от события всех его обработчиков).

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

Недочет. При выполнении программы может возникнуть ситуация, когда одна или обе кнопки не будут отображаться в окне (если, например, кнопки были перемещены на новое место при развернутом окне, после чего окно возвращено в исходное состояние).

Исправление. Определите для окна обработчик события SizeChanged:




Результат. Теперь в ситуации, когда при изменении размера окна его кнопки оказываются вне клиентской части, происходит перемещение этих кнопок на исходные позиции около левого верхнего угла окна.