none
Interaction.Triggers中EventTrigger无法捕获冒泡路由事件 RRS feed

  • 问题

  • 首先直接上代码:

    <Window x:Class="MyValidationRule.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:MyValidationRule"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            mc:Ignorable="d"
            DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
            Title="MainWindow" Height="450" Width="800">
        <i:Interaction.Behaviors>
            <local:ValidationExceptionBehaviors/>
        </i:Interaction.Behaviors>
        <Window.Resources>
            <Style TargetType="HeaderedContentControl">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="HeaderedContentControl">
                            <StackPanel Orientation="Horizontal">
                                <ContentPresenter ContentSource="Header" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                                <ContentPresenter ContentSource="Content" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="HeaderedItemsControlStyle1" TargetType="{x:Type HeaderedItemsControl}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type HeaderedItemsControl}">
                            <StackPanel>
                                <ContentPresenter ContentSource="Header"/>
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </Border>
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
      
        </Window.Resources>
    
        <Grid>
            <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="MyStackPanel">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="TextChanged">
                        <i:InvokeCommandAction Command="{Binding TextChangedCommand}" CommandParameter="{Binding ElementName=MyStackPanel, Path=BindingGroup}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <StackPanel.BindingGroup>
                    <BindingGroup x:Name="MyBindingGroup">
                        <BindingGroup.ValidationRules>
                            <local:SortValidation ValidationStep="ConvertedProposedValue" ValidatesOnTargetUpdated="True"/>
                        </BindingGroup.ValidationRules>
                    </BindingGroup>
                </StackPanel.BindingGroup>
    
                <!--<HeaderedContentControl Header="AAAA:" Margin="0 10 0 0" >
                    <TextBox Text="1231"/>
                </HeaderedContentControl>
    
                <HeaderedItemsControl Margin="0 10 0 0" Header="BBBBB:" ItemsSource="{Binding MyList}" Style="{DynamicResource HeaderedItemsControlStyle1}">
                </HeaderedItemsControl>-->
    
                <TextBox Style="{DynamicResource ValidationTextBox}">
                    <Binding Path="Age0"  NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:NotEmptyValidationRule  ValidatesOnTargetUpdated="True"/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox>
                <!--<Button Margin="0 10 0 0" Content="Submit" Command="{Binding SubmitCommand}"/>-->
                <TextBox Margin="0 10 0 0" Style="{DynamicResource ValidationTextBox}">
                    <Binding Path="Age1" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
                        <!--<Binding.ValidationRules>
                            <local:AgeValidationRule Max="120" Min="0" ValidatesOnTargetUpdated="True"/>
                            <local:PrimeNumberValidation ValidatesOnTargetUpdated="True"/>
                        </Binding.ValidationRules>-->
                    </Binding>
                </TextBox>
                <TextBox Margin="0 10 0 0" Style="{DynamicResource ValidationTextBox}">
                    <Binding Path="Age2"  NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
                        <!--<Binding.ValidationRules>
                            <local:AgeValidationRule Max="80" Min="20" ValidatesOnTargetUpdated="True"/>
                        </Binding.ValidationRules>-->
                    </Binding>
                </TextBox>
            </StackPanel>
        </Grid>
    </Window>
    

    问题就出在这一部分:

    <i:Interaction.Triggers>
                    <i:EventTrigger EventName="TextChanged">
                        <i:InvokeCommandAction Command="{Binding TextChangedCommand}" CommandParameter="{Binding ElementName=MyStackPanel, Path=BindingGroup}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>

    我的想法是:TextBoxBase 的TextChanged路由事件是一个冒泡模式,所以在stack panel中会捕获到,并且可以成功转换为命令。但是实时是没有触发那一个命令。

    之后我做了如下验证:

    1、确认TextChanged事件是否为冒泡模式的。我直接在window中添加了一个该事件的处理器,可以成功响应,说明是一个冒泡的。

    2、我猜想可能是在StackPanel中 EventTrigger没有识别出TextChanged。但是我改为TextBoxBase.TextChanged还是没有作用。

    3、我猜想EventTrriger是不是不支持路由事件。于是我又尝试了TextBox的一个隧道模式的路由事件,奇怪的是可以触发那一个绑定的命令。

    那么问题就是我上面的代码为什么不能触发那个命令,可以有上面办法解决这个问题吗

    2020年3月20日 7:41

全部回复

  • Hi,

    我从没有像你这样写过代码,你是希望Textbox里的TextChanged事件向上冒泡,然后触发StackPanel里面的TextChanged事件?先不说StackPanel没有TextChanged事件,你也没有在TextBox里面写上TextChanged事件。如果你想TextBox的TextChanged触发什么,你还是直接把代码写在TextBox里面。

    Best Regards,

    Alex

    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。


    2020年3月23日 7:04
  • hi,Alex

    这是 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    里面的功能,大意就是把路由事件转换为命令,因为使用了MVVM框架。你说的那种写法肯定是没有问题的,但也不是我需要的。

    2020年3月24日 8:15