How can I access a property path of each object in ItemsSource of a ListView from a DataTemplate? I'm trying something like
public class Person : INotifyPropertyChanged
{
private string _name;
public string Name
{
get {return _name;}
set
{
_name = value;
OnPropertyChanged();
}
}
}
public partial class MyControl : UserControl, INotifyPropertyChanged
{
private ObservableCollection<Person> _persons;
public ObservableCollection<Person> Persons
{
get {return _persons;}
set
{
_persons = value;
OnPropertyChanged();
}
}
}
<!-- MyControl.xaml.cs -->
<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<ListView ItemsSource="{Binding Persons}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name1" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Name2">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}"
Text="{Binding Name}" TextAlignMent="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
In MyControl.xaml.cs, When I use DisplayMemberBinding in a GridViewColumn of a ListView, the Name Property of each Person object in the ItemsSource Persons can be directly bound as in Name1. But when I set a DataTemplate to a GridViewColumn in order, for example, to manually set TextAlignMent as in Name2, it is impossible to directly access the Name Property of each Person object in the ItemsSource Persons.
I resolved this problem by using TemplatedParent as shown in the code above. Although this code normally works and I can get what I'm aiming to, the VisualStudio warns me with the message "Can't resolve the symbol" in the part of Text="{Binding Name}". Is there a simpler and more appropriate way to realize this kind of DataBinding?
You just bind to the Name property
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" TextAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
And you don't need to do this:
<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
The DataContext is accesible to the entire tree.
If you're not using MVVM you can set the datacontext in code behind:
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
...
If you get this to work, errors and warnings in Output Window are just false positives