WPF:获取堆栈面板中触摸的项目索引

时间:2014-05-26 15:29:26

标签: c# wpf stackpanel touch-event

我有一个StackPanel。 StackPanel的内容在数据模板中定义,它们基本上是另一个由两个按钮和两个文本块组成的StackPanel。现在......当我触摸StackPanel时,我可以通过

获取触摸的元素
e.TouchDevice.DirectlyOver

其中e是TouchEventArgs变量。但是我只能获得实际的UIElement ......我很想获得我触及的StackPanel元素的索引。

任何人都知道如何做到这一点?

谢谢。

XAML:

        <DataTemplate x:Key="AddBookListTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="9.9*"/>
                    <ColumnDefinition Width="0.1*"/>
                </Grid.ColumnDefinitions>
                <StackPanel Orientation="Vertical"  >
                    <StackPanel Orientation="Horizontal">
                        <Button blabla>
                        </Button>
                        <Button blabla>
                        </Button>
                    </StackPanel>
                    <TextBlock/>
                    <TextBlock/>
                </StackPanel>
            </Grid>
        </DataTemplate>

并重复使用

                <ScrollViewer>
                    <ItemsControl ItemsSource="{Binding Books}" Margin="0 10 0 0"  Background="Transparent" ItemTemplate="{StaticResource AddBookListTemplate}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Vertical" TouchEnter="StackPanel_TouchEnter"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                    </ItemsControl>
                </ScrollViewer>

2 个答案:

答案 0 :(得分:3)

您可以在面板的IndexOf集合中使用Children方法:

private void panel_Touch(object sender, RoutedEventArgs e)
{
    MessageBox.Show("You've touched n°" + panel.Children.IndexOf(sender as UIElement));
}

答案 1 :(得分:1)

您可以使用VisualTreeHelper向上走可视树,然后使用IndexOf()来获取索引:

    private void panel_Touch(object sender, RoutedEventArgs e)
    {
        int index;

        var button = sender as Button;
        if (button != null)
        {
            var contentPresenter = VisualTreeHelper.GetParent(button) as ContentPresenter;
            if (contentPresenter != null)
            {
                var stackPanel = VisualTreeHelper.GetParent(contentPresenter) as StackPanel;
                if (stackPanel != null)
                    index = stackPanel.Children.IndexOf(contentPresenter);
            }
        }
    }

使用像Snoop这样的工具来查看可视树,以便了解所期望的类型(我认为StackPanel将ContentPresenters放在每个项目周围,但我可能错了)。

但这有点像黑客。我建议更像这样的东西:

<StackPanel Orientation="Horizontal">
    <Button Content="OK" Command="{Binding OKCommand}" />
    <Button Content="Cancel" Command="{Binding CancelCommand}" />
</StackPanel>

RelayCommands上的OKCommand和CancelCommand为ViewModel