ManIkWeet
ManIkWeet

Reputation: 1338

XAML ListView auto width column

I'm trying to develop an universal app for personal use, however I am running into the problem that the second column in my ListView doesn't align properly, I have the following XAML:

<ListView 
        Grid.Row="1"

        ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="1*" />
                    </Grid.RowDefinitions>
                    <Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Stretch="None" Source="{Binding Image}" />
                    <TextBlock Grid.Column="0" Grid.Row="2" Text="{Binding Name}" HorizontalAlignment="Center" />
                    <Image Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Source="{StaticResource HighAlchImage}" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

Which results in the following image:
enter image description here

However, I want the second image (the one that's the same every time) to align with itself, preferably with the width of the first Column to be Auto. Is this possible?

Upvotes: 1

Views: 2725

Answers (4)

Juan Pablo Gomez
Juan Pablo Gomez

Reputation: 5534

Searching for a solution, I ended up here, @Ryan answer is near to solve my problem, but some adjusts must be done.

1 Create An style:

<Style x:Key="LstViewItemContainerStyle" TargetType="ListViewItem">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>

2 Apply style to the list view as this:

<ListView
    ...
    ItemContainerStyle="{StaticResource LstViewItemContainerStyle}">
</ListView>

Upvotes: 0

Ryan
Ryan

Reputation: 815

You need to stretch width of the ListViewItem to the width of the ListView.

i.e. You have to set HorizontalContentAlignment of the ListView's ItemContainerStyle to Stretch.

Normally I would create a copy of the Default ListViewItemStyle, then do my customization based on the default style:

(put the following code inside <ListView> Tag)

<ListView.Resources>
    <!-- Better to put this to another XAML file -->
    <Style x:Key="ListViewItemStyleDefault" TargetType="ListViewItem">
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
        <Setter Property="TabNavigation" Value="Local"/>
        <Setter Property="IsHoldingEnabled" Value="True"/>
        <Setter Property="Padding" Value="12,0,12,0"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
        <Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <ListViewItemPresenter CheckBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" ContentMargin="{TemplateBinding Padding}" CheckMode="Inline" ContentTransitions="{TemplateBinding ContentTransitions}" CheckBoxBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}" FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" PointerOverForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" PressedBackground="{ThemeResource SystemControlHighlightListMediumBrush}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" PointerOverBackground="{ThemeResource SystemControlHighlightListLowBrush}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedPressedBackground="{ThemeResource SystemControlHighlightListAccentHighBrush}" SelectionCheckMarkVisualEnabled="True" SelectedForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" SelectedPointerOverBackground="{ThemeResource SystemControlHighlightListAccentMediumBrush}" SelectedBackground="{ThemeResource SystemControlHighlightListAccentLowBrush}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ListViewItemStyleStretch" TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemStyleDefault}">
        <!-- Magic here -->
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    </Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
    <StaticResource ResourceKey="ListViewItemStyleStretch"/>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
    <!-- Your ItemTemplate... -->
</ListView.ItemTemplate>

Upvotes: 3

Grx70
Grx70

Reputation: 10349

The Grid panel has such functionality built in. In order to utilize it you should set SharedSizeGroup on your column definitions, and then set attached Grid.IsSharedSizeScope on the element parenting all grids which should share column sizes (ListView would be a good choice in your case).

<ListView Grid.Row="1"
          ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}"
          Grid.IsSharedSizeScope="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
                    <ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="1*" />
                    <RowDefinition Height="1*" />
                </Grid.RowDefinitions>
                <Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Stretch="None" Source="{Binding Image}" />
                <TextBlock Grid.Column="0" Grid.Row="2" Text="{Binding Name}" HorizontalAlignment="Center" />
                <Image Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Source="{StaticResource HighAlchImage}" />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

You might want to take some care while choosing values for SharedSizeGroup properties - preferably, they should be unique per visual tree.

Upvotes: 1

Nawed Nabi Zada
Nawed Nabi Zada

Reputation: 2875

Do it the opposite:

<Grid.ColumnDefinitions>
   <ColumnDefinition Width="Auto" />
   <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

This way your first column will use the space it needs and the second column will be aligned.

Upvotes: 0

Related Questions