代码之家  ›  专栏  ›  技术社区  ›  Milan Nosáľ

如何检测当前选定数据透视项的标题

  •  2
  • Milan Nosáľ  · 技术社区  · 9 年前

    我有一个 Pivot 控制我想要一个特殊的行为——每次用户点击当前选择的标题时 PivotItem ,我想对此做出反应。但是,当点击的标题不属于当前选定的透视项目时,不会发生这种反应。

    我的计划如下:

    对于每个 数据透视项 创建自定义标头并将其tap事件与处理程序关联:

    <phone:PivotItem DataContext="{Binding}" ContentTemplate="{StaticResource MyTemplate}" Content="{Binding}" x:Name="itemA">
        <phone:PivotItem.Header>
            <TextBlock x:Name="headerA" Text="A" Tap = "HeaderA_Tapped"/>
        </phone:PivotItem.Header>
    </phone:PivotItem>
    

    在处理程序中,测试所点击的项目当前是否被选中,如果是,则做出反应:

    protected void HeaderA_Tapped(object sender, GestureEventArgs e)
    {
        if (mainPivot.SelectedItem.Equals(itemA))
        {
            //selected item is the same pivotItem that reported tapping event
            react();
        }
    }
    

    这看起来很简单,但在尝试之后,我发现只有在选择更改事件之后才会报告轻敲事件。在用户点击当前未选中的pivotItem标题的情况下,pivot将相应地更改选择(我希望保留的默认行为),然后才报告点击事件。然而,这对我的代码来说太晚了,因为此时点击的标题和当前选择的项目已经相同。

    是否有任何方法可以检测轻敲是否启动了选择更改?还是有办法恢复事件的顺序?我猜目前WP事件模型将事件从可视化树的根向下下沉到叶子->因此 支点 更快地处理它,然后才能到达标题 TextBlock .

    3 回复  |  直到 9 年前
        1
  •  1
  •   Bao Nguyen    9 年前

    我认为您应该使用计时器跟踪Pivot SelectedIndex并更新Selection_Changed事件中的SelectedIndex。 有些人这样想:

    int selectedIndex;
    func Selection_ChangedEvent()
    {
        //use a timer to update selectedIndex
        //something like: Timer.do(selectedIndex = Pivot.SelectedIndex, 100)
        //fire after a specify time. adjust this for the best result. 
    }
    

    在你的点击事件中

    HeaderA_Tapped()
    {
        if(selectedIndex == "index of item A in Pivot")
        {
            react();
        }
    }
    
        2
  •  0
  •   Ajay    9 年前

    创建透视选择更改事件

    <phone:Pivot Title="MY APPLICATION" x:Name="MainPivot" SelectionChanged="Pivot_SelectionChanged">
    

    将事件处理程序添加到 反恐精英 文件

    private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        switch (MainPivot.SelectedIndex)
        {
            case 0:
                // do something
                break;
            case 1:
                //do something
                break;
        }
    }
    

    有关详细信息,请参阅此搜索 https://www.google.co.in/?gfe_rd=cr&ei=Y1XdVZruLqfG8AfUuquIAQ&gws_rd=ssl#q=wp8+c%23+pivot+selectionchanged

    https://social.msdn.microsoft.com/forums/windowsapps/en-US/1baf74fa-0ddd-4226-a02d-a7fc9f80374d/pivot-static-header-like-twitter-app

        3
  •  0
  •   Milan Nosáľ    9 年前

    好的,所以读了我的 Windows Phone 8开发内部 安德鲁·怀特彻普和肖恩·麦肯纳(别问我为什么不早点做)的书我找到了一个可行的解决方案。

    我不会对事件进行全面详细的讨论,只是为了指出与我的问题相关的结论。在WP8事件模型中,似乎至少有两种类型的事件,低级路由事件和逻辑触摸手势事件。路由的事件通过可视化树从最具体的元素(在我的例子中是头 TextBlock 控件)到根(因此 Pivot 应该稍后得到)。逻辑事件不会被路由,它们只出现在单个元素上(例如,我的 控件 控件),因此必须在特定元素上注册它们的处理程序。我假设逻辑事件是由元素基于较低级别的路由事件引发的。应用到我的案例中,似乎首先是下层 MouseLeftButtonDown (或按钮启动)事件已引发,路由到 支点 用它来改变选择 控件 控件创建了逻辑 Tap 事件这将导致我在模拟器上观察到的行为。我不确定路由事件是如何真正路由的,以及逻辑事件是如何创建的,所以如果我在结论中犯了错误,请纠正我。然而,我能够解决我的问题。

    使用上述假设,我决定监听较低级别的路由事件,而不是逻辑敲击手势。使用此 MouseLeftButtonUp 在新的 PivotItem 因此,我有机会检查 鼠标左键向上 由当前选定的发起 数据透视项 .

    最后,解决方案是:

    我的XAML 支点 定义(注意,现在我正在处理 鼠标左键向上 上的事件 控件 控件,而不是逻辑控件 水龙头 事件):

    <phone:Pivot Title="Pivot" Name="mainPivot">
        <phone:PivotItem DataContext="{Binding A}" ContentTemplate="{StaticResource MyTemplate}" Content="{Binding A}">
            <phone:PivotItem.Header>
                 <TextBlock Text="A" MouseLeftButtonUp="HeaderHandlerA"/>
            </phone:PivotItem.Header>
        </phone:PivotItem>
    
        <phone:PivotItem DataContext="{Binding B}" ContentTemplate="{StaticResource MyTemplate}" Content="{Binding B}">
            <phone:PivotItem.Header>
                 <TextBlock Text="B" MouseLeftButtonUp="HeaderHandlerB"/>
            </phone:PivotItem.Header>
        </phone:PivotItem>
    </phone:Pivot>
    

    因为我有不同的处理程序 数据透视项 头,我可以简单地用常量测试所选索引。代码后面的相应处理程序:

    private void HeaderHandlerA(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        // HeaderHandlerA is allways called within the first PivotItem,
        // therefore I can just test whether selected index is 0 (index of the first PivotItem)
        if (mainPivot.SelectedIndex == 0)
        {
            OnSelectedItemTapped();
        }
        // else the "tapped" header was not the selected one and I do nothing
    }
    
    private void HeaderHandlerB(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        if (mainPivot.SelectedIndex == 1)
        {
            OnSelectedItemTapped();
        }
    }
    

    也许不是最优雅的解决方案,但它很有效。。。