WPFでListBoxのアイテムにProgressBarを入れることを考えます。実際に使うときには、ItemTemplateを使ってバインドするのですが、簡単のために直にデータを書くとこんな感じになります。
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <ListBox> <ListBox.Items> <ListBoxItem> <StackPanel> <TextBlock>Download Windows 7 Release Candidate with a TechNet Plus Subscription.</TextBlock> <ProgressBar Height="12" Value="50" /> </StackPanel> </ListBoxItem> </ListBox.Items> </ListBox> </Page>
これだと、TextBlockのサイズに合わせてプログレスバーの長さが変わってしまうので、HorizontalContentAlignmentを指定して幅を広げるようにします。
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <ListBox> <ListBox.Resources> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> </Style> </ListBox.Resources> <ListBox.Items> <ListBoxItem> <StackPanel> <TextBlock>Download Windows 7 Release Candidate with a TechNet Plus Subscription.</TextBlock> <ProgressBar Height="12" Value="50" /> </StackPanel> </ListBoxItem> </ListBox.Items> </ListBox> </Page>
さらにウィンドウのサイズを小さくすると横スクロールバーが出てしまうのに対処するために、MaxWidthをScrollViewerのビューポートの幅に設定するようにします。
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <ListBox> <ListBox.Resources> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="MaxWidth" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=ViewportWidth}" /> </Style> </ListBox.Resources> <ListBox.Items> <ListBoxItem> <StackPanel> <TextBlock>Download Windows 7 Release Candidate with a TechNet Plus Subscription.</TextBlock> <ProgressBar Height="12" Value="50" /> </StackPanel> </ListBoxItem> </ListBox.Items> </ListBox> </Page>
するとなぜだかウィンドウのサイズを小さくしたときに、コンテンツが右に移動してしまうようになります。Virtualizing Stack Panel doesn't resize correctlyによると、これは.NET Frameworkのバグのようです。VirtualizingStackPanelを使わなければ大丈夫なようなので、ListBoxのItemsPanelを普通のStackPanelにすると直ります。
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <ListBox> <ListBox.Resources> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="MaxWidth" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=ViewportWidth}" /> </Style> </ListBox.Resources> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.Items> <ListBoxItem> <StackPanel> <TextBlock TextTrimming="CharacterEllipsis">Download Windows 7 Release Candidate with a TechNet Plus Subscription.</TextBlock> <ProgressBar Height="12" Value="50" /> </StackPanel> </ListBoxItem> </ListBox.Items> </ListBox> </Page>
ついでに、TextBlockにTextTrimmingを指定してはみ出た部分を「...」にするようにしています。
ただし、VirtualizingStackPanelの代わりにStackPanelを使っている都合上、アイテムの数が多くなるとパフォーマンス的に問題が出るかもしれません。