如何在Windows Phone Silverlight中访问ListBox中的内部ItemsControl



我正在构建一个小型Windows Phone应用程序,该应用程序以数据绑定的ListBox为主控件。该ListBoxDataTemplate是数据绑定的ItemsControl元素,它显示了一个人何时点击ListBox元素。

目前,我通过遍历应用程序的可视化树并在列表中引用它来访问它,然后通过SelectedIndex属性获取所选项目。

有更好或更有效的方法吗?

这一功能目前运行,但我担心它在较大列表的情况下是否仍然有效。

感谢

您是否尝试连接ListBox的SelectionChanged事件?

<ListBox ItemsSource="{Binding}" SelectionChanged="ListBox_SelectionChanged">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <!-- ... -->
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

后面的代码中有这个:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBox listBox = sender as ListBox;
    // nothing selected? ignore
    if (listBox.SelectedIndex != -1)
    {
         // something is selected
    }
    // unselect the item so if they press it again, it takes the selection
    listBox.SelectedIndex = -1;
}
ListBoxItem item = this.lstItems.ItemContainerGenerator.ContainerFromIndex(yourIndex) as ListBoxItem;

然后您可以使用VisualTreeHelper类来获取子项

var containerBorder = VisualTreeHelper.GetChild(item, 0) as Border;
var contentControl = VisualTreeHelper.GetChild(containerBorder, 0);
var contentPresenter = VisualTreeHelper.GetChild(contentControl, 0);
var stackPanel = VisualTreeHelper.GetChild(contentPresenter, 0) as StackPanel; // Here the UIElement root type of your item template, say a stack panel for example.
var lblLineOne = stackPanel.Children[0] as TextBlock; // Child of stack panel
lblLineOne.Text = "Some Text"; // Updating the text.

另一种选择是使用WP7Toolkit中提供的GestureServices类的服务。

您需要在DataTemplate的根元素中添加一个GestureListner,如下所示:

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Controls:GestureService.GestureListener>
                            <Controls:GestureListener Tap="GestureListener_Tap" />
                        </Controls:GestureService.GestureListener>
                        <TextBlock x:Name="lblLineOne" Text="{Binding LineOne}" />
                        <TextBlock Text="{Binding LineTwo}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>

在GestureListener_Tap事件处理程序中,您可以使用以下代码段。

    private void GestureListener_Tap(object sender, GestureEventArgs e)
    {
        var itemTemplateRoot = sender as StackPanel;
        var lbl1 = itemTemplateRoot.Children[0] as TextBlock;
        MessageBox.Show(lbl1.Text);
    }

我不确定GestureListner是如何在内部识别被点击的项目的,但我猜它使用了VisualTreeHelper,至少这个方法更简洁。

最新更新