Search code examples
wpflistviewdata-binding

Control template for ListViewItem - how to access property of item


Solved: I was an idiot and trusted the editors information that the DataContext is wrong. The solution is simply

<TextBlock Text="{Binding A}" />

I added a TextBlock beneath each displayed Item of a ListView. For this I used a ControlTemplate with the target type set to "ListViewItem". I put the GridViewRowPresenter and the TextBlock into a StackPanel.

<ListView ItemsSource="{Binding Items}">

   <ListView.Resources>
      <ControlTemplate x:Key="CustomListViewItemTemplate" TargetType='{x:Type ListViewItem}'>
         <StackPanel>
            <GridViewRowPresenter Content="{TemplateBinding Content}"
                                  Columns="{TemplateBinding GridView.ColumnCollection}"/>
            <TextBlock Text="{Binding }" /> <!-- here I fail -->
         </StackPanel>
      </ControlTemplate>
   </ListView.Resources>

   <ListView.ItemContainerStyle>
      <Style TargetType="ListViewItem">
         <Setter Property="Template" Value="{StaticResource CustomListViewItemTemplate}"/>
      </Style>
   </ListView.ItemContainerStyle>

   <ListView.View>
      <GridView> 
            ... 
      </GridView>
   </ListView.View>

</ListView>

The ItemsSource of the ListView is a ObservableCollection Items = new ObservableCollection<Item>(); with Item as

    public class Item
    {
        public string A { get; set; }
        public string B { get; set; }
        public string C { get; set; }
    }

I can access the ListViewItem in the ControlTemplate, but not the Item itself. Is there a possibility bind the TextBlock in the ControlTemplate to e.g. the Property "A" of each instance of Item?


Solution

  • With <ListView ItemsSource="{Binding Items}"> you specify which collection (In this case Items) provides data for the ListView. Within the template, if you assign the value "{Binding}", you effectively assign an Item from your collection you specified as ItemsSource. To assign a binding to a property of your Item, you already found the solution

    <TextBox Text="{Binding A}"/>
    

    Additionally to your current solution,

    <TextBlock Text="{Binding Path=A, Mode=TwoWay}"/>
    

    above syntax allows you to navigate to nested members, and set additional binding related parameters like Mode, UpdateSourceTrigger, Converter etc.