WPF, балонни събития
По-долу е примерна програма, която демонстрира разпространение на бълбукащо събитие:
Този пример създава прост прозорец, който демонстрира бълбукане на събитие. Ако щракнете върху която и да е част от етикета, събитията ще се задействат в реда, посочен в текстовия панел по-долу. Фигурата показва изгледа на този прозорец веднага след като потребителят щракне върху изображението в етикета. Събитието MouseUp преминава през пет нива и спира в MainWindow.
В този пример има още нещо. Ако зададете флага chb_ShowFirstEvent, методът Some_Clicked() задава свойството RoutedEventArgs.Handled на true, което спира последователността на бълбукане на събитие веднага щом се случи. Следователно ще видите само първото събитие в списъка, както е показано на фигурата:
Тук имаме нужда от допълнителен актьорски състав, т.к свойството CheckBox.IsChecked е булева стойност, която може да бъде нула (bool?, не bool). Нулевата стойност представлява неопределеното състояние на квадратчето за отметка, което означава, че то не е нито отметнато, нито изчистено. Тази функция не се използва в този пример, така че простото кастинг ще бъде достатъчно.
Тъй като методът Some_Clicked() обработва събитието MouseUp, което се случва на обекта Window, щракванията могат да бъдат уловени в текстовия панел и на празната повърхност на прозореца. Въпреки това, събитието MouseUp не се задейства, когато се щракне върху бутона Изчисти (който премахва всички записи от текстовия панел). Това е така, защото бутонът има интересна част от кода, който блокира събитието MouseUp и задейства събитие Click от по-високо ниво. В същото време флагът Handled е зададен на true, което блокира допълнителнопромоция на събитието MouseUp.
За разлика от Windows Forms контролите, повечето WPF контроли нямат събитие Click. Вместо това те имат по-простите събития MouseDown и MouseUp. Събитието Click е запазено за контроли на бутони.
Обработка на блокирано събитие
Интересното е, че има начин да получавате събития, които са маркирани като обработени. Вместо да прикачвате манипулатор на събития чрез XAML, използвайте метода AddHandler(), обсъден по-рано. Този метод има претоварване, което приема булева стойност в третия параметър. Ако го зададете на true, ще получите събитието, дори ако за него е зададен флагът Handled:
Подобно решение рядко е успешно. Бутонът е предназначен да блокира събитието MouseUp по много проста причина: за да се избегне объркване. Всъщност в Windows е прието, че можете да "щракнете" върху бутон с помощта на клавиатурата и по няколко други начина. Ако погрешно обработите събитието MouseUp на елемента Button вместо събитията Click, вашият код ще реагира само на щраквания с мишката, а не на еквивалентните действия на клавиатурата.