Как я могу получить доступ к элементам управления в DataTemplate в ListBox в WPF

У меня есть ListBox, включая ItemTemplate со StackPanel. Я хочу получить доступ к этой стековой панели и изменить ее видимость.

(Измените его видимость на свернутую, когда я нажимаю кнопку мыши с кнопкой "closeAll")

Я могу сделать это с помощью метода FindDescendantByName, но он работает только для элементов списка на экране (только первые 10 элементов), но при прокрутке вниз я вижу, что это не работает для других элементов списка.

I think that errors occurs because of VisualTreeHelper. What can I use instead of VisualTreeHelper?

Спасибо..

XAML CODE

<ListBox x:Name="listBoxEditPast"  SelectionMode="Single"  Margin="0" Background="#272B34" ScrollViewer.VerticalScrollBarVisibility="Visible">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Border Grid.Row="0"   BorderThickness="4,0,0,0" Margin="2,0,0,0" Height="29"  Background="#2E323B" Width="1050" BorderBrush="#1373A9" MouseLeftButtonDown="Border_MouseLeftButtonDown">
                    <DockPanel Name="dockPanelPast" Margin="0,4,0,0">
                        <Image Name="imgArrow" Source="images/down-arrow.png" HorizontalAlignment="Left" Width="20" Height="18"/>
                        <TextBlock Text="{Binding CreateDate}" Name="txtTarih" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16"/>
                        <TextBlock Text="{Binding SarjNo}" Name="txtSarjNo" Foreground="#FF9CA518" HorizontalAlignment="Stretch" VerticalAlignment="Center" FontSize="16" Margin="50,0,0,0" Width="90"/>
                        <TextBlock Text="{Binding Adi}" Name="txtReceteAdi" Foreground="#FF26A053"  VerticalAlignment="Center" FontSize="16" Margin="40,0,0,0" HorizontalAlignment="Stretch"/>
                         <Button Content="Detaylar" Style="{StaticResource BlueButton}" HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" DockPanel.Dock="Right"/>
                    </DockPanel>
                </Border>
                <StackPanel Grid.Row="1"  Name="stackPanelDetay" Tag="{Binding ID}">
                    <DockPanel>
                        <TextBlock Text="Sipariş No" Foreground="#D9480F" VerticalAlignment="Center" />
                        <TextBlock Text="Parça" Foreground="#AF0FD9" VerticalAlignment="Center" Margin="50,0,0,0" Width="200" />
                        <TextBlock Text="Malzeme" Foreground="White" VerticalAlignment="Center" Margin="150,0,0,0" Width="90"/>
                        <TextBlock Text="Müşteri" Foreground="#AF0FD9" VerticalAlignment="Center" Margin="70,0,0,0" />
                    </DockPanel>
                    <DockPanel>
                        <TextBlock Text="{Binding ID}" Foreground="White"  VerticalAlignment="Center" Width="100"/>
                        <TextBlock Text="{Binding ParcaKoduAdi}" Foreground="White"  VerticalAlignment="Center" Margin="5,0,0,0" Width="200"  />
                        <TextBlock Text="{Binding Malzeme}" Foreground="White"  VerticalAlignment="Center" Margin="152,0,0,0" Width="90" />
                        <TextBlock Text="{Binding MusteriKoduAdi}" Foreground="White"  VerticalAlignment="Center" Margin="70,0,0,0" />
                    </DockPanel>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Код C#

public static class FrameworkElementExtensions
{
    public static FrameworkElement FindDescendantByName(this FrameworkElement element, string name)
    {
        if (element == null || string.IsNullOrWhiteSpace(name)) { return null; }

        if (name.Equals(element.Name, StringComparison.OrdinalIgnoreCase))
        {
            return element;
        }
        var childCount = VisualTreeHelper.GetChildrenCount(element);
        for (int i = 0; i < childCount; i++)
        {
            var result = (VisualTreeHelper.GetChild(element, i) as FrameworkElement).FindDescendantByName(name);
            if (result != null) { return result; }
        }
        return null;
    }
}

private void closeAll_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // StackPanel panel = LayoutHelper.FindElement(listBoxEditPast, n => n.GetType() == typeof(StackPanel)) as StackPanel;

    for (int i = 0; i < listBoxEditPast.Items.Count; i++)
    {
        var element = listBoxEditPast.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;
        if (element != null)
        {
            var sp = element.FindDescendantByName("stackPanelDetay") as StackPanel;
            if (sp != null)
            {
                sp.Visibility = Visibility.Collapsed;
            }
        }
    }
}

1 ответ

Не говоря уже о Visualtreehelper, это потому, что список виртуализирован, поэтому создаются только первые десять элементов, а затем заменяются десятью следующими.... и вы теряете свои модификации

Вы не должны работать с элементом в шаблоне данных по коду

итерируйте ваши данные, чтобы установить логическое значение true/false для всех, а затем измените стек и свяжите видимость с этим логическим значением

 <StackPanel Grid.Row="1" Name="stackPanelDetay" Visibility="{Binding myBoolean, Converter=BoolToVisibility}">
Другие вопросы по тегам