MouseEventArgs
имеет свойство OriginalSource
. Это свойство this, которое содержит ссылку на объект, который его изначально вызвал.
Аргумент sender
совершенно справедливо установлен для экземпляра объекта, к которому вы прикрепили обработчик события. Возможно, простой эксперимент покажет, как все это выглядит лучше. В Visual Studio создайте приложение Silverlight. Сделайте так, чтобы содержимое MainPage.xaml выглядело так: -
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid x:Name="LayoutRoot" Background="White" MouseLeftButtonDown="MouseHandler">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel x:Name="OuterPanel" MouseLeftButtonDown="MouseHandler" Margin="5">
<StackPanel x:Name="TopPanel" MouseLeftButtonDown="MouseHandler">
<TextBlock Text="First Top Item" />
<TextBlock Text="Second Top Item" />
</StackPanel>
<StackPanel x:Name="BottomPanel" MouseLeftButtonDown="MouseHandler">
<TextBlock Text="First Bottom Item" />
<TextBlock Text="Second Bottom Item" />
</StackPanel>
</StackPanel>
<ListBox x:Name="lstOutput" Grid.Column="1" Margin="5" />
</Grid>
</UserControl>
И в MainPage.xaml.cs добавьте этот код: -
private void MouseHandler(object sender, MouseButtonEventArgs e)
{
FrameworkElement s = sender as FrameworkElement;
TextBlock o = e.OriginalSource as TextBlock;
string text = (o != null) ? o.Text : "Not from a text block";
lstOutput.Items.Add(String.Format("Sender: {0}, Text block: {1}", s.Name, text));
}
Обратите внимание, как этот же обработчик присоединен к трем различным элементам в XAML, но не к самим TextBlocks. Нажав на «Первый топовый предмет», вы получите следующее: -
Sender: TopPanel, Text block: First Top Item
Sender: OuterPanel, Text block: First Top Item
Sender: LayoutRoute, Text block: First Top Item
Обработчик запускает 3 раза один раз для каждого элемента, к которому он прикреплен, что видно по тому, что отправитель отличается для каждого. Однако OrignalSource - это TextBlock, на который фактически был нажат, несмотря на то, что к нему не подключен какой-либо обработчик. Также обратите внимание, что OriginalSource остается тем же самым, поскольку он пузырится на элементах предка.
Нажмите на область под панелями стека. Вы получаете только: -
Sender: LayoutRoot, Text block: Not from a text block
Интересно также то, что нажатие в окне списка не приводит к добавлению элементов вообще, вы можете ожидать того же, что и в приведенной выше строке. Очевидно, ListBox опускает мышь и поэтому устанавливает свойство args Handled
события на True
, предотвращая дальнейшее всплытие.