2010年8月21日土曜日

ListBoxのアイテムとして表示するUserControlの幅をひろげる

XAMLで期待したとおりにUIを表示するうちでいくつか大変な箇所があるが、今回紹介するのもそのうちの一つだ。

ケース1
ListBox内部にUserControlをアイテムとして表示する際に、内部に表示したUserControlが下図のようにListBoxの幅いっぱいまで広がってくれないことがある。


実際には下図のように表示したい。

ここからコードを交えて解説してく。

SampleUserControl - ListBox内部に表示するUserControl
SampleUserControl.xaml
<Border BorderBrush="RoyalBlue" BorderThickness="2" CornerRadius="3" HorizontalAlignment="Stretch">
  <TextBlock x:Name="_text" TextWrapping="Wrap" />
</Border>

SampleUserControl.xaml.cs
public SampleUserControl()
{
    InitializeComponent();
    _text.SetBinding(TextBlock.TextProperty, new Binding() { Source = this, Path = new PropertyPath("Text") });
}

public string Text
{
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(SampleUserControl), new PropertyMetadata("Sample Text"));

上記のコードはListBox内部に表示するUserControlの詳細になる。ListBoxからテキストをDataBindingできるようにTextをDependency Propertyにしている以外はいたって普通のコードだ。


MainPage.xaml
<UserControl.Resources>
        <Style x:Key="ListBoxItemContainerStyle" TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </UserControl.Resources>
    <Border BorderBrush="Tomato" CornerRadius="2" Padding="2" Margin="2" BorderThickness="2" Width="300" >
        <ListBox ItemsSource="{Binding TextList}"
                     ItemContainerStyle="{StaticResource ListBoxItemContainerStyle}"
                     Margin="5,5" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <application:SampleUserControl Text="{Binding}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Border>

MainPage.xaml.cs
public MainPage()
{
 InitializeComponent();
 TextList = new List<string> { 
  "Silverlightサンプル",
  "マツオソフトウェア",
  "Yoo Matsuo",
 };        
 this.DataContext = this;
}

 public List<string> TextList { get; set; }

MainPage.xamlのポイントはListBoxのItemContainerStyleに渡しているResourcesで定義したStyleだ。このStyleでHorizontalContentAlignmentをStrechとしている。これでListBox内部のアイテムがListBoxの幅いっぱいまで広がって表示されるようになる。

ケース2
ListBox内部にUserControlをアイテムとして表示する際に、内部に表示したUserControlが下図のようにListBoxの幅を超えてどこまでも広がっていってしまうことがある。


ListBoxの幅で折り返したい。

この対処方はしごく簡単で、ListBoxの宣言部に下記を追加すればよい。
ScrollViewer.HorizontalScrollBarVisibility="Disabled"

これでListBoxの幅で折り返されるはずだ。ちなみにSampleUserControl.xamlでTextBlockのTextWrapping="Wrap"を設定しているが、これを忘れると今回のサンプルではUserControlの表示そのものがListBoxの幅で切り取られてしまうので注意して欲しい。

0 件のコメント:

コメントを投稿