如何访问正在呈现的ListBox中的项,而不是其源数据

本文关键字:数据 ListBox 访问 何访问 | 更新日期: 2023-09-27 18:23:56

在这里继续我的问题

我尝试使用链接答案中提供的解决方案,但当我给它ListBox绑定到的图像时,它给了我错误的位置,因为项目模板加载的是源URL,而不是实际图像,而且数据似乎为空。

我的项目模板如下所示:

<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>

如何访问当前所选项目的"ListImage"?

如何访问正在呈现的ListBox中的项,而不是其源数据

每个ItemsControl都有一个ItemsContainerGenerator,它负责为列表中的每个项目生成一个控件。它提供了一些有用的方法来查找给定项目的容器,反之亦然。你可以这样使用它:

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

然后,您可以将变量容器与其他帖子中的解决方案一起使用,以找到坐标,

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

顺便说一句,在DataTemplate中,您不需要StackPanel,因为ListBox通过其ItemsPanelTemplate提供了StackPanel。

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

点击事件时,您可以执行以下操作:

private void image_Tap(对象发送方,System.Windows.Input.GestureEventArgs e)

{
            Image selectedImage = e.OriginalSource as Image;
}

这是你需要的吗?

我建议使用不同的解决方案,因为您试图解决它的方式(查找控件)很容易出错。

使DataTemplate成为资源,并使用ItemTemplate="{StaticResource myTemplate}" 在ListBox中引用它

接下来,当选择一个项目时,将ContentControl添加到Canvas,将其ContentTemplate设置为相同的DataTemplate,将DataContext设置为SelectedItem。

这样,您只需要定义一次模板(在一个地方维护它),而不必遍历VisualTree。