krebstar
krebstar

Reputation: 4046

ListBox or ItemControl items don't take up all available space

Sorry if this has been answered before; I've looked at similar posts here but the suggested fix isn't working for me.

I'm working on a Silverlight 3 project and I have the following:

<ListBox ItemsSource="{Binding}" 
         ItemTemplate="{StaticResource TemplateSelector}"
         >
  <ListBox.ItemContainerStyle>
     <Style TargetType="ListBoxItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
     </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

The ListBox is bound to a source, which uses different DataTemplates using a DataTemplateSelector that I implemented in Silverlight.

The ListBox seems to ignore the style property HorizontalContentAlignment, i.e. I can't get the items to stretch to the whole width of the ListBox.

My DataTemplates look like this:

<StackPanel Orientation="Horizontal">
  <TextBlock Text="{Binding DisplayName}" />
  <TextBox Text="{Binding Value}" Name="{Binding ID}"/>
</StackPanel>

Basically, I want the items to fill all the available space of the ListBox control, and share them so that the left half of the space is occupied by the TextBlock, and the right half is occupied by the TextBox.

Any ideas on how to do this?

EDIT: @wdavo: Here's the TemplateSelector code:

// http://www.codeproject.com/Articles/92439/Silverlight-DataTemplateSelector
public abstract class DataTemplateSelector : ContentControl
{
  public virtual DataTemplate SelectTemplate(
    object item, DependencyObject container)
  {
    return null;
  }

  protected override void OnContentChanged(object oldContent, object newContent)
  {

    base.OnContentChanged(oldContent, newContent);
    ContentTemplate = SelectTemplate(newContent, this);
  }
}
public class MyTemplateSelector : DataTemplateSelector
{
  public DataTemplate MyTemplate1 { get; set; }
  public DataTemplate MyTemplate2 { get; set; }
  public DataTemplate MyTemplate3 { get; set; }

  public override DataTemplate SelectTemplate(object item, DependencyObject container)
  {
    var element  = item;

    if (element.GetType() == typeof(MyType1))
      return MyTemplate1;
    else if (element.GetType() == typeof(MyType2))
      return MyTemplate2;
    else if (element.GetType() == typeof(MyType3))
      return MyTemplate3; 

    return base.SelectTemplate(item, container);
  }
}

and the xaml:

<DataTemplate x:Key="TemplateSelector">
    <local:MyTemplateSelector Content="{Binding}">
        <local:MyTemplateSelector.MyTemplate1>
            <DataTemplate>
                <StackPanel >
                    <TextBlock Text="{Binding DisplayName}" />
                    <TextBox Text="{Binding Value}" Name="{Binding ID}" />
                </StackPanel>
            </DataTemplate>
        </local:MyTemplateSelector.MyTemplate1>
        ... and so on
    </local:MyTemplateSelector>
</DataTemplate>

Upvotes: 2

Views: 2204

Answers (2)

wdavo
wdavo

Reputation: 5110

I'm guessing you need to set the HorizontalAlignment and HorizontalContentAlignment properties to stretch within your TemplateSelector.

E.g.

 <ContentPresenter
            Content="{Binding Item}">
            <ContentPresenter.ContentTemplate>
                <DataTemplate>
                    <local:TemplateSelector
                        Content="{Binding}"
                        HorizontalAlignment="Stretch"
                        HorizontalContentAlignment="Stretch">

As mentioned you should also you a Grid instead of a StackPanel

Upvotes: 2

Bryan Watts
Bryan Watts

Reputation: 1425

You should just use a Grid. The StackPanel is only using the minimum space needed by each element.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*">
        <ColumnDefinition Width="*">
    </Grid.ColumnDefinitions>
    <TextBlock Text="{Binding DisplayName}" />
    <TextBox Text="{Binding Value}" Name="{Binding ID}"/>
</Grid>

Upvotes: 4

Related Questions