Willem
Willem

Reputation: 9486

How to create a ListBox that looks like the Windows Live Tiles?

I want to create a ListBox that looks like the Windows Live Tiles.

This is my XAML:

<ListBox Name="listBox"
             Grid.Row="1"
              Background="Transparent"
              BorderBrush="Transparent"
              BorderThickness="0"
              Width="Auto" Height="Auto"
              ScrollViewer.HorizontalScrollBarVisibility="Disabled"
              ItemsSource="{Binding Path=SomeList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
              VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
              VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
    <DataTemplate >
        <Grid x:Name="PART_Item" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>


            <Image Name="logo" Source="{Binding Path=ImagePath}" 
                                Width="50" Height="50"
                               Margin="0,0,10,0"
                                   Grid.Column="0" Grid.Row="0" Grid.RowSpan="2"
                               RenderTransformOrigin="0.5,0.5"
                               SnapsToDevicePixels="True">
            </Image>

            <TextBlock Grid.Row="0" Grid.Column="1" 
                               TextAlignment="Left" 
                               FontSize="12"
                               Text="{Binding Path=SomeName}" 
                               TextTrimming="CharacterEllipsis"/>

            <TextBlock Grid.Row="1" Grid.Column="1" 
                               Margin="0,10,0,0" 
                                       FontSize="12"
                               TextAlignment="Left" 
                               Text="{Binding Path=SomeNo}" 
                               TextTrimming="CharacterEllipsis"/>

            <TextBlock Grid.Row="0" Grid.Column="2"
                               TextAlignment="Left" 
                                       FontSize="12"
                               Text="{Binding Path=SomeDescription}"
                               TextWrapping="Wrap"/>
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

I only want to to be in the above mentioned layout.

How would i achieve this?

The image is just for a reference. I want may layout to be like the first 3 Rows.

enter image description here

Upvotes: 1

Views: 3140

Answers (2)

Matthew Walton
Matthew Walton

Reputation: 9969

I'd probably do it with a WrapPanel. Give the ListBox an ItemsPanelTemplate with a WrapPanel in it:

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <WrapPanel Orientation="Horizontal" />
    </ItemsPanel>
</ListBox>

Then set your ItemTemplate up so that the size of each item is half the width of the ListBox itself (or the same width, for your example third row). The easiest way to do that is to set the ListBox to a known width, then bind the width of the top-level panel in the DataTemplate to something in the item objects. However, this means the objects need to know how wide they're supposed to be - but if they want to fill the tile sizes properly, maybe that could be seen as a benefit.

Another option is a DataTemplateSelector, but that also needs to have a way of determining if it should deliver a wide or narrow template and it doesn't really have access to information about where in the list it is - it just knows which item to deliver a template for.

If you really want to do it without the items having to know anything about where in the list they're going to appear, I think you're going to have to step back from ListBox and write more of the logic yourself. You might be able to wrangle an ItemsControl into behaving like this, but I think it's more likely you'd need to go back further still and do a full-blown custom control, depending on how much flexibility you actually want.

But judging by your question, I think you'll probably be okay just retemplating the ListBox.

Upvotes: 1

Mart
Mart

Reputation: 5788

One easy solution is to use a WrapPanel as the ListBox ItemsPanel. Make your items have the correct dimension (square or rectangle) using DataBinding and give the ListBox the width of two squares.

Upvotes: 2

Related Questions