[WPF] 解決ListBox中的Expander造成的佈局錯誤問題

  • 11189
  • 0
  • RIA
  • 2013-07-14

WPF中的ListBox預設使用的ItemsPanel是VirtualizingStackPanel,而不是一般的StackPanel,這樣在一般的使用上雖然不會發生什麼問題,但是當它一碰上Expander,問題就大條了。

 

首先,請先玩玩下面的範例,將所有的Expander展開,再將所有的Expander收合,看看兩邊有什麼不同之處:

(*若無法正常瀏覽本WPF版範例,煩請參考[Windows7]使用IE9、FireFox與Chrome瀏覽WPF Browser Application(.XBAP)的方式一文調整瀏覽器設定)

我們可以很明顯的發現,左邊的容器在Expander收合之後,還是一樣佔了大部份的版面空間,而沒有隨著Expander收合而變小。

這個其實是因為WPF中的ListBox預設使用的ItemsPanel是VirtualizingStackPanel,而不是一般的StackPanel,這樣在一般的使用上雖然不會發生什麼問題,但是當它一碰上Expander,問題就大條了。

解法呢?很簡單,把ListBox的ItemsPanel改為一般的StackPanel就行啦!!

讓我們來看看上面範例的原始碼:

Page1.xaml
<Page x:Class="Wpf_ExpanderInListBox.Page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
	  d:DesignWidth="600" d:DesignHeight="400" 
      Title="Page1">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.5*"/>
            <ColumnDefinition Width="0.5*"/>
        </Grid.ColumnDefinitions>
        <Rectangle Stroke="#FF4B4B4B" RadiusX="10" RadiusY="10" StrokeThickness="2" Grid.ColumnSpan="2"/>
        <StackPanel>
            <StackPanel Orientation="Horizontal" Margin="10,2">
                <TextBlock Text="Actual Height Of The Left ListBox: " FontSize="13.333" />
                <TextBlock Text="{Binding ActualHeight, ElementName=listBox}" FontSize="13.333" />
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="10,2">
                <TextBlock Text="Actual Height Of Expander1: " FontSize="13.333" />
                <TextBlock Text="{Binding ActualHeight, ElementName=expander1}" FontSize="13.333" />
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="10,2">
                <TextBlock Text="Actual Height Of The Black Rectangle: " FontSize="13.333" />
                <TextBlock Text="{Binding ActualHeight, ElementName=rect1}" FontSize="13.333" />
            </StackPanel>
            <ListBox Margin="5" x:Name="listBox">
            	<Expander Header="Expander1" x:Name="expander1" Height="auto" Width="auto" IsExpanded="True">
            		<Rectangle x:Name="rect1" Fill="Black" Stroke="Black" Width="280" Height="70"/>
            	</Expander>
            	<Expander x:Name="expander2" Header="Expander2">
            		<Rectangle x:Name="rect2" Fill="Red" Stroke="Black" Width="280" Height="70"/>
            	</Expander>
            	<Expander x:Name="expander3" Header="Expander3">
            		<Rectangle x:Name="rect3" Fill="White" Stroke="Black" Width="280" Height="70"/>
            	</Expander>
            </ListBox>
        </StackPanel>
        <StackPanel Grid.Column="1">
            <StackPanel Orientation="Horizontal" Margin="10,2">
                <TextBlock Text="Actual Height Of The Right ListBox: " FontSize="13.333" />
                <TextBlock Text="{Binding ActualHeight, ElementName=listBox}" FontSize="13.333" />
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="10,2">
                <TextBlock Text="Actual Height Of Expander4: " FontSize="13.333" />
                <TextBlock Text="{Binding ActualHeight, ElementName=expander1}" FontSize="13.333" />
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="10,2">
                <TextBlock Text="Actual Height Of  The Green Rectangle: " FontSize="13.333" />
                <TextBlock Text="{Binding ActualHeight, ElementName=rect1}" FontSize="13.333" />
            </StackPanel>
            <ListBox Margin="5" x:Name="listBox1">
		<!-- 加入下面這段 -->	
            	<ListBox.ItemsPanel>
            		<ItemsPanelTemplate>
            			<StackPanel Orientation="Vertical" />
            		</ItemsPanelTemplate>
            	</ListBox.ItemsPanel>
		<!-- 到這邊為止 -->
            	<Expander Header="Expander4" x:Name="expander4" Height="auto" Width="auto" IsExpanded="True">
            		<Rectangle x:Name="rect4" Fill="#FF037200" Stroke="Black" Width="280" Height="70"/>
            	</Expander>
            	<Expander x:Name="expander5" Header="Expander5">
            		<Rectangle x:Name="rect5" Fill="#FFD2DE00" Stroke="Black" Width="280" Height="70"/>
            	</Expander>
            	<Expander x:Name="expander6" Header="Expander6">
            		<Rectangle x:Name="rect6" Fill="#FF7E0193" Stroke="Black" Width="280" Height="70"/>
            	</Expander>
            </ListBox>
        </StackPanel>
    </Grid>
</Page>

就這麼簡單!!

 

最後一樣附上專案原始檔,請自行服用: