views:

133

answers:

2

I am using MVVM binding an ObservableCollection of children to an ItemsControl. The ItemsControl contains a UserControl used to style the UI for the children.

<ItemsControl  ItemsSource="{Binding Documents}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>      
            <View:DocumentView Margin="0, 10, 0, 0" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

I want to show a header row for the contents of the ItemsControl but only want to show this once at the top (not for every child). How can I implement this behaviour in the DocumentView user control? Fyi I am using a Grid layout to style the child rows:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="34"/>
        <ColumnDefinition Width="100"/>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="60" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />   
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBlock Grid.ColumnSpan="4" Grid.Row="0" Text="Should only show this at the top"></TextBlock>
    <Image Grid.Column="0" Grid.Row="1" Height="24" Width="24" Source="/Beazley.Documents.Presentation;component/Icons/error.png"></Image>        
    <ComboBox Grid.Column="1" Grid.Row="1" Name="ContentTypes" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type View:MainView}}, Path=DataContext.ContentTypes}" SelectedValue="{Binding ContentType}"/>
    <TextBox Grid.Column="2" Grid.Row="1" Text="{Binding Path=FileName}"/>
    <Button Grid.Column="3" Grid.Row="1"
        Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type View:MainView}}, Path=DataContext.RemoveFile}"
        CommandParameter="{Binding}">Remove</Button>
</Grid> 
A: 

You should be able to use the AlternationCount to work out the position of the item in your ItemsControl by setting the AlternationCount to the size of your collection.

Then apply your style only to the Item where ItemsControl.AlternationIndex = 0.

An example for a ListBox (which is an ItemsControl) assuming your collection is 5 in size:

<Grid>
  <Grid.Resources>
    <Style x:Key="alternatingWithTriggers" TargetType="{x:Type ListBoxItem}">
      <Setter Property="Background" Value="Blue"/>
      <Setter Property="Foreground" Value="White"/>
      <Style.Triggers>
        <Trigger Property="ListBox.AlternationIndex" Value="0">
          <Setter Property="Background" Value="CornflowerBlue"/>
          <Setter Property="Foreground" Value="Black"/>
        </Trigger>
      </Style.Triggers>
    </Style>

  </Grid.Resources>
  <ListBox AlternationCount="5" ItemsSource="{StaticResource data}" 
           ItemContainerStyle="{StaticResource alternatingWithTriggers}">
  </ListBox>
</Grid>

There is no doubt a way to do it without triggers too...

Schneider
A: 

On second thoughts why are you even trying to do this yourself?

Looks like you are basically just trying to create a table with custom column types... Have you tried ListView or DataGrid controls?

Schneider
Thanks, I switched to using a ListView. I didn't realise you can style it as much as I needed. Thanks for your help.
Dan Ryan
In other words - you've accepted my answer? :P
Schneider
I think that's a nudge Dan ;-)
ip