Search code examples
c#wpfxamllistviewitemcontentpresenter

WPF GridViewRowPresenter turns all the content into Textblocks


I'm trying to create a list with fully functional headers, but I can only seem to get either a list with functional headers and all list view items reduced to textblocks. OR a list view with all the buttons and text fully styled, but without the headers being properly linked. See the image below;

enter image description here

My ListView definition looks like this for both of them:

              <ListView ItemsSource="{Binding ScenarioComponents}" Style="{StaticResource ListViewWithHeader}" ItemContainerStyle="{StaticResource ListViewWithHeaderItem}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="Auto" Header="{Binding NameHeader}" DisplayMemberBinding="{Binding Name}"/>
                            <GridViewColumn Width="Auto" Header="{Binding TypeHeader}" DisplayMemberBinding="{Binding Type}"/>
                            <GridViewColumn Width="Auto" Header="{Binding InfoHeader}"/>
                            <GridViewColumn Width="Auto" Header="{Binding ExportHeader}"/>
                            <GridViewColumn Width="Auto" Header="{Binding DeleteHeader}"/>
                        </GridView>
                    </ListView.View>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="5*"/>
                                    <ColumnDefinition Width="1.5*"/>
                                    <ColumnDefinition Width="0.5*"/>
                                    <ColumnDefinition Width="0.5*"/>
                                    <ColumnDefinition Width="0.5*"/>
                                </Grid.ColumnDefinitions>
                                <Label Grid.Column="0" Content="{Binding Name}" HorizontalAlignment="Left"/>
                                <Label Grid.Column="1" Content="{Binding Type}" Background="{StaticResource XVROrange}"/>
                                <Button Grid.Column="2" Style="{StaticResource BorderLessButton}" Command="{Binding MoreInfoCommand}">
                                    <Button.Content>
                                        <Image Source="/Views/Images/cc2_gui_information_default.png"/>
                                    </Button.Content>
                                </Button>
                                <Button Grid.Column="3" Style="{StaticResource BorderLessButton}" Command="{Binding ExportCommand}">
                                    <Button.Content>
                                        <Image Source="/Views/Images/cc2_gui_export_default.png"/>
                                    </Button.Content>
                                </Button>
                                <Button Grid.Column="4" Style="{StaticResource BorderLessButton}" Command="{Binding DeleteCommand}">
                                    <Button.Content>
                                        <Image Source="/Views/Images/cc2_gui_b_delete.png"/>
                                    </Button.Content>
                                </Button>
                            </Grid>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

And the only difference in the styling is that the one with the Headers working uses a GridViewRowPresenter in the ListViewItem like this:

        <Style x:Key="ListViewWithHeaderItem" TargetType="ListViewItem">
        <Setter Property="OverridesDefaultStyle" Value="true" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border x:Name="Border" Padding="0" Background="Transparent" BorderBrush="{StaticResource XVR70}" BorderThickness="1">
                        <GridViewRowPresenter Content="{TemplateBinding Content}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

And the second one uses the same styling only with a ContentPresenter instead of the GridViewRowPresenter without any embellishments.

         <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Background="Transparent" BorderBrush="{StaticResource Black47}" BorderThickness="0,0,0,0">
                        <ContentPresenter />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

For some reason using the GridViewRowPresenter means every item in my ListView.ItemTemplate's DataTemplate gets turned into a Textblock. And I can't figure out why. I'd really prefer to keep using the GridViewRowPresenter though as this means the headers are bound to the items in the list and scale with them and everything.

Has anyone got any idea how I can style this to work?


Solution

  • Can you put your templates from the ItemTemplate into the GridViewColumns?

    <ListView.View>
      <GridView>
        <GridView.Columns>
          <GridViewColumn Width="Auto" Header="{Binding NameHeader}" DisplayMemberBinding="{Binding Name}">
            <GridViewColumn.CellTemplate>
              <DataTemplate>
                <Label Grid.Column="0" Content="{Binding Name}" HorizontalAlignment="Left"/>
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
          <!-- more columns -->
        </GridView.Columns>
      </GridView>
    </ListView.View>