andidegn
andidegn

Reputation: 137

How do you set ContentPresenter properties inside a GridViewRowPresenter?

I am trying to get the text inside my ListView to align to the top of the cells.

This is what I've done so far:

The data is bound like this:

<ListView.View>
  <GridView>
    <GridViewColumn Width="50">
      <GridViewColumn.CellTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor,
                                        AncestorType={x:Type ListViewItem}},
                                    Converter={StaticResource lviIndexToString}}"
                     Foreground="White"
                     VerticalAlignment="Top"/>
        </DataTemplate>
      </GridViewColumn.CellTemplate>
    </GridViewColumn>
    <GridViewColumn Width="80">
      <GridViewColumn.CellTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding LogTime}"
                     Foreground="{StaticResource ConsoleOrange}"/>
        </DataTemplate>
      </GridViewColumn.CellTemplate>
    </GridViewColumn>
    <GridViewColumn Width="80">
      <GridViewColumn.CellTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding MessageType}"
                     Foreground="{Binding MessageType,
                         Converter={StaticResource logMsgToColor}}"/>
        </DataTemplate>
      </GridViewColumn.CellTemplate>
    </GridViewColumn>
    <GridViewColumn DisplayMemberBinding="{Binding Path=Message}"/>
  </GridView>
</ListView.View>

the ItemContainer is styled like this:

<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="ListViewItem">
      <Grid>
        <GridViewRowPresenter VerticalAlignment="Stretch">
          <GridViewRowPresenter.Resources>
            <Style TargetType="ContentPresenter">
              <Setter Property="Margin" Value="1"/>
              <Setter Property="VerticalAlignment" Value="Stretch"/>
            </Style>
          </GridViewRowPresenter.Resources>
        </GridViewRowPresenter>
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>

It works if the ContentPresenters VerticalAlignment is set to 'Stretch'. However, the visual tree reveals that the ContentPresenter style is being overridden by something, but I can't for the life of me figure out by what. enter image description here

If anyone have any idea how to set the nested ContentPresenters properties, or educate me in how to set up a custom GridViewRowPresenter to have more control over how to display the data, I would be most greatful.

I apologise if this has been answered elsewhere, but my google-fu search (and the search here) have not revealed any useful solutions.

Update The end goal is to align the text in the first 3 columns to the top of the ListViewItem. enter image description here

Upvotes: 5

Views: 2204

Answers (1)

AnjumSKhan
AnjumSKhan

Reputation: 9827

To override value of VerticalAlignment property ContentPresenter, we need to set it with some higher precedence step. Animation holds number 2 position in precedence order.

<ListView.Resources>
    <Style TargetType="ContentPresenter">
        <Style.Triggers>
            <EventTrigger RoutedEvent="Loaded">
                <BeginStoryboard>
                    <Storyboard >
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="VerticalAlignment">
                            <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                <DiscreteObjectKeyFrame.Value>
                                    <VerticalAlignment>Top</VerticalAlignment>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Style.Triggers>
    </Style>
</ListView.Resources>

Another approach is just to handle ContentPresenter.Loaded event and set property values there.

  <Style TargetType="ContentPresenter">
         <EventSetter Event="Loaded" Handler="ContentPresenter_Loaded"/>
  </Style>

Handler :

void ContentPresenter_Loaded(object sender, RoutedEventArgs e)
{
    (sender as ContentPresenter).VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
}

This changing of property using Loaded event handler can be done using Blend Behaviors / Attached Property too.

Upvotes: 6

Related Questions