如果在專案中必需使用ListBox做為物件呈現的容器時,若使用預設的Template,當在執行期改變ListBox寬度的時候,可能會發現,裡面的項目大小並不會跟著ListBox縮放;就算把裡面的項目水平對齊方式改為Stretch,它還是會依然故我,不管ListBox寬度的變化。
如果在專案中必需使用ListBox做為物件呈現的容器時,若使用預設的Template,當在執行期改變ListBox寬度的時候,可能會發現,裡面的項目大小並不會跟著ListBox縮放;就算把裡面的項目水平對齊方式改為Stretch,它還是會依然故我,不管ListBox寬度的變化。
但是如果直接把ListBox中的項目寬度直接寫死的話,又很容易影響整體的美感,之前在網路上有找到利用TemplateBinding來讓ListBoxItem的寬度和ViewPort的寬度做繫結的辦法,但是那個方法會使得ListBox的水平ScrollBar一直出現在畫面上,若ListBox調整大小,整個佈局也會跟著「走精」。
不過,其實只要針對ListBox的ItemContainerStyle下手,強制讓ListBoxItem的HorizontalContentAlignment屬性設為Stretch就行啦!!
讓我們來看看下面的範例:
(*若無法正常瀏覽本WPF版範例,煩請參考[Windows7]使用IE9、FireFox與Chrome瀏覽WPF Browser Application(.XBAP)的方式一文調整瀏覽器設定)
*若將滑鼠移到以左右兩個ListBox中的項目上,或是利用兩個ListBox中間的GridSplitter改變ListBox的大小,就可以看出明顯的差異。
上面的範例中,左右兩個ListBox裡面的項目都被包在一個Grid中,但是左邊ListBox裡的Grid寬度是固定的,所以不管ListBox的寬度改為多少,裡面的Buy按鈕都還是保持在同一個地方,而右邊的ListBox裡的Grid,則會隨著ListBox自動調整寬度,所以Buy按鈕始終會貼齊ListBox的右側。
要做到像右邊的ListBox的效果,只需要在Resorce中加入以下的XAML:
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
並且將ListBox的ItemContainerStyle設為{StaticResource ListBoxItemStyle}就行啦~~
來看看完整的XAML:
<Page x:Class="Wpf_StretchListBoxItem.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" Title="Page1"
d:DesignWidth="800" d:DesignHeight="600" ShowsNavigationUI="False" Width="Auto"
Height="Auto">
<Page.Resources>
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
<DataTemplate x:Key="ItemTemplate">
</DataTemplate>
</Page.Resources>
<Border BorderThickness="2" CornerRadius="10" BorderBrush="#FF323232"
DataContext="{Binding Source={StaticResource SampleDataSource}}">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<GridSplitter Width="3" Background="#FF49C8FD" />
<ListBox Margin="10" HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Collection}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="Auto" Height="Auto" UseLayoutRounding="True"
Background="Transparent" MinWidth="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.3*" />
<RowDefinition Height="0.7*" />
</Grid.RowDefinitions>
<Border HorizontalAlignment="Stretch" Margin="0" Grid.RowSpan="1"
VerticalAlignment="Center" d:LayoutOverrides="Width"
CornerRadius="3" Background="#FF292828">
<TextBlock Text="{Binding Id}" Height="15.96" FontWeight="Bold"
TextAlignment="Center" Foreground="White" Margin="5,0" />
</Border>
<TextBlock Text="{Binding Name}" Grid.RowSpan="1" Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Grid.ColumnSpan="1" d:LayoutOverrides="GridBox"
Margin="10,0,0,0" FontWeight="Bold" FontSize="13.333" />
<Image Source="{Binding Picture}" HorizontalAlignment="Left" Height="64"
Width="64" Grid.Row="1" VerticalAlignment="Center"
Grid.Column="1" Margin="0" Grid.ColumnSpan="1" />
<TextBlock Text="{Binding Price}" Grid.RowSpan="1" Grid.Row="1"
HorizontalAlignment="Right" VerticalAlignment="Center"
Grid.Column="1" Margin="0" d:LayoutOverrides="Width"
FontWeight="Bold" FontSize="16" Foreground="Red" />
<Button x:Name="button" Content="Buy" Grid.Column="2"
Margin="8,7.96,8,19.96" Grid.RowSpan="1" Width="50" Height="50"
HorizontalAlignment="Center" VerticalAlignment="Center"
Grid.Row="1" Visibility="Hidden" />
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Visibility" TargetName="button" Value="Visible" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Grid.Column="1" Margin="10" HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Collection}"
ItemContainerStyle="{StaticResource ListBoxItemStyle}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid UseLayoutRounding="True" Background="Transparent" Height="Auto"
Width="Auto" MinWidth="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="0.903*" />
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.3*" />
<RowDefinition Height="0.7*" />
</Grid.RowDefinitions>
<Border HorizontalAlignment="Stretch" Margin="0" Grid.RowSpan="1"
VerticalAlignment="Center" d:LayoutOverrides="Width"
CornerRadius="3" Background="#FF292828">
<TextBlock Text="{Binding Id}" Height="15.96" FontWeight="Bold"
TextAlignment="Center" Foreground="White" Margin="5,0" />
</Border>
<TextBlock Text="{Binding Name}" Grid.RowSpan="1" Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Grid.ColumnSpan="1" d:LayoutOverrides="GridBox"
Margin="10,0,0,0" FontWeight="Bold" FontSize="13.333"
Foreground="White" />
<Image Source="{Binding Picture}" HorizontalAlignment="Left" Height="64"
Width="64" Grid.Row="1" VerticalAlignment="Center"
Grid.Column="1" Margin="0" Grid.ColumnSpan="1" />
<TextBlock Text="{Binding Price}" Grid.RowSpan="1" Grid.Row="1"
HorizontalAlignment="Right" VerticalAlignment="Center"
Grid.Column="1" Margin="0" d:LayoutOverrides="Width"
FontWeight="Bold" FontSize="16" Foreground="Red" />
<Button x:Name="button" Content="Buy" Grid.Column="2"
Margin="8,7.96,8,19.96" Grid.RowSpan="1" Width="50" Height="50"
HorizontalAlignment="Center" VerticalAlignment="Center"
Grid.Row="1" Visibility="Hidden" />
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Visibility" TargetName="button" Value="Visible" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</Page>
就這麼簡單!!
最後一樣附上專案原始碼,請自行服用: