Search code examples
c#wpfdatatemplate

Show only item on which user clicks, collapse others


I have comment section with comments and to each comment can be left reply. It looks like this:

<ListBox x:Name="list" ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemsSource="{Binding Comments}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock x:Name="comment" FontSize="15" Foreground="Black" Text="{Binding Text}" TextWrapping="Wrap" Margin="0,1,0,5" Padding="{Binding Depth, Converter={StaticResource LevelToPaddingConverter}, ConverterParameter=15}"/>
                <Grid Grid.Row="1">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="auto"/>
                     </Grid.ColumnDefinitions>
                     <StackPanel Orientation="Horizontal">
                         <TextBlock x:Name="author" Style="{StaticResource commentInfo}" Text="{Binding UserId, Converter={StaticResource UserIdToUserNameConverter}}" Padding="{Binding Depth, Converter={StaticResource LevelToPaddingConverter}, ConverterParameter=15}"/>
                         <TextBlock Text="," Style="{StaticResource commentInfo}"/>
                         <TextBlock x:Name="timeAgo" Style="{StaticResource commentInfo}" Text="{Binding CreatedAt, Converter={StaticResource TimestampToAgoConverter}}"/>
                     </StackPanel>
 <!-- THIS BUTTON --><HyperlinkButton x:Name="reply" Grid.Column="1" FontSize="10" Foreground="Blue" Content="Reply" HorizontalAlignment="Right" Tapped="reply_Tapped"/>
                     <StackPanel x:Name="replyBox" Visibility="Collapsed" Margin="0,19,0,0">
                         <TextBox PlaceholderText="Write Comment..." FontSize="11" BorderBrush="Gray" BorderThickness="1" Margin="0,0,0,3" Height="50" GotFocus="TextBox_GotFocus" LostFocus="commentBox_LostFocus" TextWrapping="Wrap"/>
                         <Button Content="Post Reply" FontSize="12" Background="CornflowerBlue" BorderThickness="0" Style="{StaticResource ButtonStyle1}" Width="75" Height="25" HorizontalAlignment="Right" Tapped="PostCommentButton_Tapped"/>
                     </StackPanel>
                 </Grid>
             </StackPanel>
         </DataTemplate>
     </ListBox.ItemTemplate>
 </ListBox>

And when user clicks on that button, TextBox and Button for commentig becomes visible. But if users then clicks reply on another comment, there are two TextBoxes visible(each for the relevant comment). But I want that when user clicks reply to another comment, the previous TextBox would collapse, so only one TextBox is visible at the time. How can I do that?


Solution

  • I found solution. I iterate through all StackPanels in control and find those with name replyBox and then I collapse them.
    I did that like this:

    foreach (StackPanel sp in FindVisualChildren<StackPanel>(this))
    {
        if (sp.Name == "replyBox")
        {
            sp.Visibility = Visibility.Collapsed;
        }
    }
    //and here showing function for the one I wnat to be visible
    

    And FindVisualChildren function looks like this:

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }
    
                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }
    

    I got idea from this answer