我正在构建一个小型Windows Phone应用程序,该应用程序以数据绑定的ListBox
为主控件。该ListBox
的DataTemplate
是数据绑定的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,至少这个方法更简洁。