Reputation: 16999
The problem is, if you click the button and expand the phone number, the stackpanel & border expand, which is great, but if you collapse it, the stackpanel & border do not collapse.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Background="White"
>
<StackPanel>
<Border BorderBrush="Black" BorderThickness="1">
<ListBox x:Name="myListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Background="LightBlue" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="John Smith"/>
<Button Click="Button_Click" Width="25" Height="25"/>
</StackPanel>
<StackPanel x:Name="PhoneNumber" Visibility="Collapsed">
<TextBlock Text="12345"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</StackPanel>
</Window>
With the following code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
myListBox.ItemsSource = new List<int>() { 1, 2 }; //add 2 elements;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
StackPanel sp1 = VisualTreeHelper.GetParent(btn) as StackPanel;
StackPanel sp2 = VisualTreeHelper.GetParent(sp1) as StackPanel;
StackPanel phone = sp2.FindName("PhoneNumber") as StackPanel;
if (phone.Visibility == System.Windows.Visibility.Collapsed)
phone.Visibility = System.Windows.Visibility.Visible;
else
phone.Visibility = System.Windows.Visibility.Collapsed;
myListBox.UpdateLayout(); //these don't collapse my space
this.UpdateLayout(); //these don't collapse my space
}
}
}
Upvotes: 4
Views: 6744
Reputation: 41403
The issue is that the Listbox is using virtualization. If you disable that then the issue goes away, like so:
<ListBox x:Name="myListBox" BorderBrush="Black" BorderThickness="1">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Alternatively, you can leave the default ItemsPanel and set ScrollViewer.CanContentScroll="False"
on the ListBox. Both disable virtualization though.
I believe this question is related.
Upvotes: 1
Reputation: 84684
Didn't dig to deep into this but it looks like you'll have to call InvalidateMeasure
all the way up the chain to the ItemsPresenter
(actually, the ItemsPanelTemplate
). I'll update if I can up with something better
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
StackPanel sp1 = VisualTreeHelper.GetParent(btn) as StackPanel;
StackPanel sp2 = VisualTreeHelper.GetParent(sp1) as StackPanel;
StackPanel phone = sp2.FindName("PhoneNumber") as StackPanel;
if (phone.Visibility == System.Windows.Visibility.Collapsed)
phone.Visibility = System.Windows.Visibility.Visible;
else
phone.Visibility = System.Windows.Visibility.Collapsed;
DependencyObject dpObject = btn;
while (dpObject != null)
{
if (dpObject is UIElement)
{
(dpObject as UIElement).InvalidateMeasure();
}
if (dpObject is ItemsPresenter)
break;
dpObject = VisualTreeHelper.GetParent(dpObject);
}
}
Upvotes: 3