简体   繁体   English

路由事件的TargetType

[英]TargetType for routed events

We have TargetType for style, so that we can say please, only buttons : 我们为样式提供了TargetType ,因此我们只能说按钮

<Style TargetType="Button">
    ...
</Style>

However, take to example this snippet: 但是,以以下代码段为例:

<TabControl >
    <TabControl.Triggers>
        <EventTrigger RoutedEvent="TabControl.SelectionChanged">
            ...
        </EventTrigger>
    </TabControl.Triggers>
    <TabItem>
        <ListBox>
            <ListBoxItem>1</ListBoxItem>
            <ListBoxItem>2</ListBoxItem>
        </ListBox>
    </TabItem>
</TabControl>

We have something (to example, animation) attached to trigger when TabControl (it's even specified in xaml, but doing nothing as a fact) SelectionChanged event occurs. TabControl (甚至在xaml中指定,但实际上不执行任何操作) SelectionChanged事件发生时,我们会附加一些触发器(例如动画)。 This, however, will happily occurs when ListBox selected item is changed as well. 但是,这也会在ListBox所选项目也发生更改时发生。

It's a nature of routed events, because as there is no handler in ListBox , it will be routed to its parent. 这是路由事件的一种性质,因为ListBox没有处理程序,它将被路由到其父级。 We could simply use code behind 我们可以在后面简单地使用代码

private void Stop(object sender, SelectionChangedEventArgs e)
{
    e.Handled = true;
}

and attach it to every child , like this: 并将其附加到每个孩子 ,如下所示:

 <ListBox SelectionChanged="Stop">
 ...
 </ListBox>

However, imagine there are hundreds of children and at some point we decide to animate their parent. 但是,想象有数百个孩子,并且在某个时候我们决定为父母做动画。 Now we have to go through all children and attach them to bloody event handler . 现在我们必须遍历所有孩子并将他们附加到血腥事件处理程序中 Right? 对?

No, it's not right. 不,这是不对的。 There should be something missing. 应该缺少一些东西。 An ability to specify a scope or type or anything (make event trigger strict to declaration). 指定范围类型或任何内容的能力(使事件触发器严格执行声明)。 Or perhaps some dirty hack. 或一些肮脏的技巧。 Anyone knows anything like this? 有人知道吗?

PS: tagged as MVVM, because code-behind is not as good if it is possible to avoid it. PS:标记为MVVM,因为如果可以避免,则隐藏代码的效果不佳。

I believe that your problem is caused because both TabControl and ListBox override the Selector.SelectionChanged event . 我相信您的问题是由于TabControlListBox覆盖了Selector.SelectionChanged事件而引起的。 I would however agree with you that if (as we have) we specify that we want to use the overridden TabControl event, this shouldn't be confused with the Listbox.SelectionChanged event as it is. 但是,我同意您的看法,如果(如我们Listbox.SelectionChanged )指定要使用重写的TabControl事件,则不应将其与Listbox.SelectionChanged事件混淆。 It might even be an idea to leave a bug report on the Microsoft Connect website. 将错误报告保留在Microsoft Connect网站上甚至是一个主意。

However, there is one fix that I can think of, but it might not suit you... it really depends on what you are doing when the selection of the ListBox es change. 但是,我可以想到一种解决方法,但它可能不适合您...它实际上取决于ListBox的选择更改时您在做什么。 What we can do is to add a handler to each ListBox.SelectionChanged event and set the SelectionChangedEventArgs.Handled property to be true , so that it does not interfere with the SelectionChanged event of the TabControl : 我们可以做的是向每个ListBox.SelectionChanged事件添加一个处理程序,并将SelectionChangedEventArgs.Handled属性设置为true ,以免干扰TabControlSelectionChanged事件:

<TabControl>
    <TabControl.Triggers>
        <EventTrigger RoutedEvent="TabControl.SelectionChanged">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation From="0.25" To="1.0" Duration="0:0:1" 
                        Storyboard.TargetProperty="Opacity" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </TabControl.Triggers>
    <TabItem Header="Tab 1">
        <ListBox SelectionChanged="ListBox_SelectionChanged">
            <ListBoxItem>1</ListBoxItem>
            <ListBoxItem>2</ListBoxItem>
        </ListBox>
    </TabItem>
    <TabItem Header="Tab 2">
        <ListBox SelectionChanged="ListBox_SelectionChanged">
            <ListBoxItem>1</ListBoxItem>
            <ListBoxItem>2</ListBoxItem>
        </ListBox>
    </TabItem>
</TabControl>

... ...

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    e.Handled = true;
}

If you want to do something when the selection changes on either ListBox , then I suggest that you use the SelectedItem property to manage that instead and then you won't miss the ListBox.SelectionChanged event. 如果要在两个ListBox上的选择更改时执行某些操作,则建议您使用SelectedItem属性代替它来进行管理,这样您就不会错过ListBox.SelectionChanged事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM