Bob
Bob

Reputation: 1625

How do I get access to the item in a ListBox that is being rendered rather than its source data?

In a continuation from my question here

I tried using the solution provided in the linked answer, however when I give it the image which the ListBox is binding to, it gives me the wrong position, because the Item Template is loading in a source URL rather than the actual image, and it seems the data is null.

My Item Template looks like this:

<ListBox ItemsSource="{Binding Items}"
                     HorizontalContentAlignment="Left"
                     VerticalContentAlignment="Center"  
                     ScrollViewer.VerticalScrollBarVisibility="Disabled"
                     ScrollViewer.HorizontalScrollBarVisibility="Visible" 

                     Height="64" Name="listBoxSource" 
                     VerticalAlignment="Bottom" 
                     SelectionChanged="listBoxSource_SelectionChanged" Canvas.Left="32" Canvas.Top="365" Width="596"
             >

                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                        <Image x:Name="ListImage" Source="{Binding thumbnailURL}" Height="64" Width="64"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

            </ListBox>

How do I get access to "ListImage" for the currently selected Item?

Upvotes: 2

Views: 1976

Answers (3)

ChimeraObscura
ChimeraObscura

Reputation: 1964

Every ItemsControl has an ItemsContainerGenerator, which (surprisingly enough) is responsible for generating a control for each item in the list. It provides a few useful methods for finding the container of a given item, and vice versa. You can use it like this:

private void listBoxSource_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var listBox = (ListBox) sender;
    var containerGenerator = listBox.ItemContainerGenerator;
    var container = (UIElement)containerGenerator.ContainerFromItem(listBox.SelectedItem);
}

You can then use the variable container with the solution from your other post to find the coordinates,

Point position = container.GetRelativePosition(Application.Current.RootVisual);

And on a side note, in your DataTemplate you don't need the StackPanel, since the ListBox is providing that with its ItemsPanelTemplate.

<DataTemplate>
    <Image x:Name="ListImage" Source="{Binding thumbnailURL}" Height="64" Width="64"/>
</DataTemplate>

Upvotes: 1

Igor Meszaros
Igor Meszaros

Reputation: 2127

on tap event you can do this:

private void image_Tap(object sender, System.Windows.Input.GestureEventArgs e)

{
            Image selectedImage = e.OriginalSource as Image;
}

is this what you need?

Upvotes: 1

Emond
Emond

Reputation: 50672

I would suggest a different solution because the way you are trying to solve it (finding the control) is prone to error.

Make the DataTemplate a resource and refer to it in the ListBox by using ItemTemplate="{StaticResource myTemplate}"

Next, when an item is selected, add a ContentControl to the Canvas, set its ContentTemplate to the same DataTemplate and the DataContext to the SelectedItem.

This way you only have to define the template once (one place to maintain it) and do not have to walk the VisualTree.

Upvotes: 0

Related Questions