如何使用 DataTemplate 访问列表框中的特定项目? [英] How to access a specific item in a Listbox with DataTemplate?

查看:27
本文介绍了如何使用 DataTemplate 访问列表框中的特定项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ListBox,其中包含一个带有 2 个 StackPanel 的 ItemTemplate.我想访问的第二个 StackPanel 中有一个 TextBox.(将其可见性更改为 true 并接受用户输入)触发器应该是 SelectionChangedEvent.因此,如果用户单击 ListBoxItem,则 TextBlock 不可见,而 TextBox 可见.

I have a ListBox including an ItemTemplate with 2 StackPanels. There is a TextBox in the second StackPanel i want to access. (Change it's visibility to true and accept user input) The trigger should be the SelectionChangedEvent. So, if a user clicks on an ListBoxItem, the TextBlock gets invisible and the TextBox gets visible.

XAML 代码:

<ListBox Grid.Row="1" Name="ContactListBox" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Contacts}" Margin="0,36,0,0" SelectionChanged="ContactListBox_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,0">
                        <toolkit:ContextMenuService.ContextMenu>
                            <toolkit:ContextMenu>
                                <toolkit:MenuItem Header="Edit Contact" Click="ContactMenuItem_Click"/>
                                <toolkit:MenuItem Header="Delete Contact" Click="ContactMenuItem_Click"/>
                            </toolkit:ContextMenu>
                        </toolkit:ContextMenuService.ContextMenu>

                        <Grid>
                            <Rectangle Fill="{StaticResource PhoneAccentBrush}"
                                           Width="72" Height="72">
                                <Rectangle.OpacityMask>
                                    <ImageBrush ImageSource="/Images/defaultContactImage.png" Stretch="UniformToFill"/>
                                </Rectangle.OpacityMask>
                            </Rectangle>
                        </Grid>
                        <StackPanel>
                            <TextBox Text="{Binding Name}" TextWrapping="Wrap" Visibility="Collapsed"/>
                            <TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" />
                            <TextBlock Text="{Binding Number}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextAccentStyle}"/>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

我想有几种方法可以解决这个问题,但我尝试过的方法都没有奏效.

I guess there are several ways to solve this, but nothing I tried worked.

我目前的方法是这样的

    private void ContactListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListBoxItem listBoxItem = ContactListBox.SelectedItem as ListBoxItem;

        DataTemplate listBoxTemplate = listBoxItem.ContentTemplate;

        // How to access the DataTemplate content?

        StackPanel outerStackPanel = listBoxTemplate.XXX as StackPanel;

        StackPanel innerStackPanel = outerStackPanel.Children[1] as StackPanel;

        TextBox nameBox = innerStackPanel.Children[0] as TextBox;
        TextBlock nameBlock = innerStackPanel.Children[1] as TextBlock;


        nameBox.Visibility = System.Windows.Visibility.Visible;
        nameBlock.Visibility = System.Windows.Visibility.Collapsed;

    }

推荐答案

感谢你们的帮助!!最后我得到了它.解决了 VisualTreeHelper 的问题.好棒的功能^^

Thank you for your help guys!! Finally i got it. Solved the problem with the VisualTreeHelper. What a great function ^^

private void ContactListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (ContactListBox.SelectedIndex == -1)
            return;

        currentSelectedListBoxItem = this.ContactListBox.ItemContainerGenerator.ContainerFromIndex(ContactListBox.SelectedIndex) as ListBoxItem;

        if (currentSelectedListBoxItem == null)
            return;

        // Iterate whole listbox tree and search for this items
        TextBox nameBox = helperClass.FindDescendant<TextBox>(currentSelectedListBoxItem);
        TextBlock nameBlock = helperClass.FindDescendant<TextBlock>(currentSelectedListBoxItem);

helperFunction

public T FindDescendant<T>(DependencyObject obj) where T : DependencyObject
    {
        // Check if this object is the specified type
        if (obj is T)
            return obj as T;

        // Check for children
        int childrenCount = VisualTreeHelper.GetChildrenCount(obj);
        if (childrenCount < 1)
            return null;

        // First check all the children
        for (int i = 0; i < childrenCount; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child is T)
                return child as T;
        }

        // Then check the childrens children
        for (int i = 0; i < childrenCount; i++)
        {
            DependencyObject child = FindDescendant<T>(VisualTreeHelper.GetChild(obj, i));
            if (child != null && child is T)
                return child as T;
        }

        return null;
    }

这篇关于如何使用 DataTemplate 访问列表框中的特定项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆