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

发布于 2024-11-14 17:13:31 字数 364 浏览 3 评论 0原文

我正在构建一个小型 Windows Phone 应用程序,它有一个数据绑定 ListBox 作为主控件。该 ListBoxDataTemplate 是一个数据绑定 ItemsControl 元素,当用户点击 ListBox 元素时会显示该元素。

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

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

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

谢谢

I am building a small Windows Phone application which has a databound ListBox as a main control. DataTemplate of that ListBox is a databound ItemsControl element, which shows when a person taps on a ListBox element.

Currently, I am accessing it by traversing the visual tree of the application and referencing it in a list, and than getting the selected item through SelectedIndex property.

Is there a better or more effective way?

This one works currently, but I am afraid if it would stay effective in case of larger lists.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

已下线请稍等 2024-11-21 17:13:31

您是否尝试过连接 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;
}

Have you tried wiring the SelectionChanged event of the ListBox?

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

With this in the code behind:

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;
}
烟─花易冷 2024-11-21 17:13:31
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.

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

您需要将 GestureListner 添加到 DataTemplate 的根元素,如下所示:

            <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,至少这个方法更简洁。

ListBoxItem item = this.lstItems.ItemContainerGenerator.ContainerFromIndex(yourIndex) as ListBoxItem;

Then you can use the VisualTreeHelper class to get the sub items

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.

Another option is to use services of the GestureServices class available in the WP7 Toolkit.

You'll need to add a GestureListner to the Root Element of your DataTemplate like so:

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

And in the GestureListener_Tap event handler, you use this snippet.

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

I'm not sure how the GestureListner recognize internally the item being tapped but I guess that it uses the VisualTreeHelper, at least this method is more concise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文