如何检测点击当前选定的 PivotItem 的 header
How to detect a tap on header of currently selected PivotItem
我有一个 Pivot
控件。我想要一种特殊的行为——每次用户点击当前选择的 PivotItem
的 header 时,我都想对此做出反应。但是,当点击的 header 不属于当前选择的枢轴项时,不会发生此反应。
我的计划如下:
为每个 PivotItem
创建一个自定义 header 并将其点击事件与处理程序相关联:
<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 header 的情况下,pivot 将相应地更改选择(我想保留的默认行为),然后才报告点击事件。但是,这对我的代码来说为时已晚,因为在那一刻点击的 header 和当前选择的项目已经相同。
有什么方法可以检测点击是否启动了选择更改?或者有没有办法恢复事件的顺序?我想目前 WP 事件模型将事件从 Visual Tree 的根部下沉到叶子 -> 因此 Pivot
会更快地处理它,然后它才会到达 header TextBlock
.
创建枢轴选择更改事件
<phone:Pivot Title="MY APPLICATION" x:Name="MainPivot" SelectionChanged="Pivot_SelectionChanged">
将事件处理程序添加到 cs 文件
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
我认为您应该使用计时器跟踪 Selection_Changed 事件中的 Pivot SelectedIndex 和更新 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();
}
}
好的,所以在阅读了我的 Windows Phone 8 Development Internals Andrew Whitechapel 和 Sean McKenna 的书之后(不要问我为什么这样做不要早点做)我有一个可行的解决方案。
我不会对事件进行全面详细的讨论,只是指出与我的问题相关的结论。似乎在 WP8 事件模型中至少有两种类型的事件,较低级别的路由事件和逻辑触摸手势事件。路由事件通过可视树从最具体的元素(在我的例子中是 header TextBlock
控件)路由到根(因此 Pivot
应该稍后得到它)。逻辑事件不被路由,它们只出现在单个元素上(例如,我的 TextBlock
控件),因此它们的处理程序必须在特定元素上注册。我假设逻辑事件是由基于较低级别路由事件的元素引发的。适用于我的情况,似乎首先引发了 lower-level MouseLeftButtonDown
(或按下按钮)事件,路由到 Pivot
用于更改选择,然后才是我的 TextBlock
控件创建了逻辑 Tap
事件。这将导致我在模拟器上观察到的行为。我不确定路由事件的真正路由方式以及逻辑事件的创建方式,所以如果我的结论有误,请指正。但是,我能够解决我的问题。
使用上述假设,我决定监听 lower-level 路由事件而不是逻辑点击手势。使用此 MouseLeftButtonUp
事件,我在选择新的 PivotItem
之前收到通知,因此让我有机会检查引发的 MouseLeftButtonUp
是否由当前选择的 PivotItem
.[=28 发起=]
最后的解决方案是:
我的 XAML Pivot
定义(请注意,现在我正在处理 TextBlock
控件上的 MouseLeftButtonUp
事件,而不是逻辑 Tap
事件):
<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>
因为每个 PivotItem
header 我都有不同的处理程序,我可以简单地用一个常量测试选定的索引。 code-behind:
中对应的handlers
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();
}
}
也许不是最优雅的解决方案,但它确实有效...
我有一个 Pivot
控件。我想要一种特殊的行为——每次用户点击当前选择的 PivotItem
的 header 时,我都想对此做出反应。但是,当点击的 header 不属于当前选择的枢轴项时,不会发生此反应。
我的计划如下:
为每个 PivotItem
创建一个自定义 header 并将其点击事件与处理程序相关联:
<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 header 的情况下,pivot 将相应地更改选择(我想保留的默认行为),然后才报告点击事件。但是,这对我的代码来说为时已晚,因为在那一刻点击的 header 和当前选择的项目已经相同。
有什么方法可以检测点击是否启动了选择更改?或者有没有办法恢复事件的顺序?我想目前 WP 事件模型将事件从 Visual Tree 的根部下沉到叶子 -> 因此 Pivot
会更快地处理它,然后它才会到达 header TextBlock
.
创建枢轴选择更改事件
<phone:Pivot Title="MY APPLICATION" x:Name="MainPivot" SelectionChanged="Pivot_SelectionChanged">
将事件处理程序添加到 cs 文件
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
我认为您应该使用计时器跟踪 Selection_Changed 事件中的 Pivot SelectedIndex 和更新 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();
}
}
好的,所以在阅读了我的 Windows Phone 8 Development Internals Andrew Whitechapel 和 Sean McKenna 的书之后(不要问我为什么这样做不要早点做)我有一个可行的解决方案。
我不会对事件进行全面详细的讨论,只是指出与我的问题相关的结论。似乎在 WP8 事件模型中至少有两种类型的事件,较低级别的路由事件和逻辑触摸手势事件。路由事件通过可视树从最具体的元素(在我的例子中是 header TextBlock
控件)路由到根(因此 Pivot
应该稍后得到它)。逻辑事件不被路由,它们只出现在单个元素上(例如,我的 TextBlock
控件),因此它们的处理程序必须在特定元素上注册。我假设逻辑事件是由基于较低级别路由事件的元素引发的。适用于我的情况,似乎首先引发了 lower-level MouseLeftButtonDown
(或按下按钮)事件,路由到 Pivot
用于更改选择,然后才是我的 TextBlock
控件创建了逻辑 Tap
事件。这将导致我在模拟器上观察到的行为。我不确定路由事件的真正路由方式以及逻辑事件的创建方式,所以如果我的结论有误,请指正。但是,我能够解决我的问题。
使用上述假设,我决定监听 lower-level 路由事件而不是逻辑点击手势。使用此 MouseLeftButtonUp
事件,我在选择新的 PivotItem
之前收到通知,因此让我有机会检查引发的 MouseLeftButtonUp
是否由当前选择的 PivotItem
.[=28 发起=]
最后的解决方案是:
我的 XAML Pivot
定义(请注意,现在我正在处理 TextBlock
控件上的 MouseLeftButtonUp
事件,而不是逻辑 Tap
事件):
<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>
因为每个 PivotItem
header 我都有不同的处理程序,我可以简单地用一个常量测试选定的索引。 code-behind:
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();
}
}
也许不是最优雅的解决方案,但它确实有效...