Почему объект аргументов моего туннелирующего события и объект аргументов пузырькового события не равны?

#routedevent #routedeventargs

#routedevent #routedeventargs

Вопрос:

Я работаю над книгой 70-511 и просматриваю раздел о маршрутизируемых событиях. Я заметил, что в нем упоминается, что пары событий bubbling-tunneling используют один и тот же экземпляр EventArgs , поэтому, если вы обрабатываете событие туннелирования (например, PreviewMouseDown ), оно останавливает парное событие bubbling (например, MouseDown); Я пробовал это, и это работает… Но, если я проверяю на равенство каждый раз, когда срабатывает обработчик событий (для целей тестирования я использую 1 обработчик событий для обоих событий), кажется, что EventArgs НЕ являются одним и тем же экземпляром (т. Е. Они имеют разные хэш-значения, а Object.Equals возвращает false)… Это значительно улучшило бы мое понимание того, как работают маршрутизируемые события, если бы я мог понять, почему это так!

Какие-нибудь .NET-гуру, которые там хотят объяснить?

Я проверил книгу Pro WPF (отличная книга), и в ней также просто говорится: «Чтобы сделать жизнь интереснее, если вы пометите событие туннелирования как обработанное, событие пузырьков не произойдет. Это потому, что два события используют один и тот же экземпляр класса RoutedEventArgs . «

Если два события используют ОДИН и ТОТ ЖЕ ЭКЗЕМПЛЯР класса, разве eventargs не должны иметь одинаковые хэш-значения и возвращать ‘True’ для Object.Equals???

 private RoutedEventArgs args;

private void MouseDownHandler(object sender, MouseButtonEventArgs e)
{
    listEvents.Items.Add(string.Format("{0} - {1} - {2} - {3}",
        sender.GetType().Name, e.RoutedEvent.ToString(), e.Source.GetType().Name,
        e.OriginalSource.GetType().Name));
    listEvents.Items.Add(e.GetHashCode().ToString());
    if (args != null) listEvents.Items.Add(e.Equals(args).ToString());
    args = e;
}
  

XAML:

 <Window x:Class="Chapter_2___WPF_RoutedEvents.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="428" Width="658"
    PreviewMouseDown="MouseDownHandler" MouseDown="MouseDownHandler">
    <Grid Name="grid"
          MouseDown="MouseDownHandler" PreviewMouseDown="MouseDownHandler">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ListBox Name="listEvents" Grid.Column="1"/>
        <Button Content="Click Me!" Width="150" Height="50" Margin="10" Grid.Column="0"
                MouseDown="MouseDownHandler" PreviewMouseDown="MouseDownHandler"/>
    </Grid>
</Window>
  

Ответ №1:

Когда я запускаю ваш код и нажимаю кнопку, он возвращает тот же хэш-код и «True» для e.Equals(args) . Если я нажимаю снова, e.Equals(args) возвращает ‘False’, потому что это новый экземпляр RoutedEventArgs для каждого щелчка, но следующий возвращается True , потому что событие туннелирования совпадает с событием пузырьков.