2

I have a StackPanel. The contents of the StackPanel are defined in a Data Template and they are basically another StackPanel composed of two Buttons and two Text Blocks. Now... when I touch the StackPanel I can get the element I touched through

e.TouchDevice.DirectlyOver

Where e is a TouchEventArgs variable. But I can only get the actual UIElement... I'm intrested in getting the index of the element of the StackPanel that I touched.

Anyone knows how to do that?

Thank you.

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>

And is reused

                <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>
Marco
  • 1,454
  • 1
  • 16
  • 30
  • 1
    post your XAML. BTW a `StackPanel` is just a Panel. It does not deal with Items. you should be using an `ItemsControl` or a derivative such as a `ListBox`. – Federico Berasategui May 26 '14 at 15:34

2 Answers2

3

You could simply use the IndexOf method on the panel's Children collection:

private void panel_Touch(object sender, RoutedEventArgs e)
{
    MessageBox.Show("You've touched n°" + panel.Children.IndexOf(sender as UIElement));
}
Pragmateek
  • 13,174
  • 9
  • 74
  • 108
  • No because the contents of the panel aren't UIElements. – Marco May 26 '14 at 15:56
  • With the XAML this is better. :) I fear you may have to resort to walk the **visual tree** with the `VisualTreeHelper` to get the root of the current item. Then you'll be able to use `IndexOf` on the `Items` collection of your `ItemsControl`. – Pragmateek May 26 '14 at 16:11
3

You could use VisualTreeHelper to walk up the visual tree, and then use IndexOf() to get the index:

    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);
            }
        }
    }

Use a tool like Snoop to view the visual treee so you know what types to expect (I think that StackPanel puts ContentPresenters around each item, but I could be wrong).

It's a bit of a hack though. I'd recommend something more like this:

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

Where OKCommand and CancelCommand are RelayCommands on your ViewModel.

Community
  • 1
  • 1
MatrixManAtYrService
  • 8,023
  • 1
  • 50
  • 61
  • This worked great for me. To avoid deep nesting I had a line of statements like 1. `Button? button = parameter as Button;` 2. `if(button == null) throw new ArgumentNullException(nameof(Button));` and continued to work my way up to the `StackPanel`. – Connell Hagen Aug 23 '23 at 19:18