I want to bind a DataGrid to a Collection of nested Properties.
I tried with the solution from
WPF: Bound datagrid does not update items properties
but with no luck so far.
What i get is an empty DataGrid and Console output like that:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=AGNR.Key; DataItem=null; target element is 'DataGridTextColumn' (HashCode=38805039); target property is 'Header' (type 'Object')
Also Output from tcc_CollectionChanged (but not PropertyChangedHandler):
30.12.2016 11:11:22, Collection changed
I use the Modern UI (firstfloor) framework. Here is my code for the Window:
public partial class Home : UserControl
{
private ObservableTable<TableClass> tcc;
public Home()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
TableClass tc;
List<TableClass> tcl = new List<TableClass>();
tcc = new ObservableTable<TableClass>();
tcc.CollectionChanged += tcc_CollectionChanged;
tcc.ItemPropertyChanged += PropertyChangedHandler;
for (int i = 0; i < 10; i++)
{
tc = new TableClass();
tc.AGNR.Name = "AGNr";
tc.AGNR.Value = i.ToString();
tc.MNR.Name = "MNr";
tc.MNR.Value = i.ToString() + " M";
tc.MST.Name = "MSt";
tc.MST.Value = i % 2 == 0 ? "production" : "stopped";
tcc.Add(tc);
}
}
static void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString() + ", Property changed");
return;
}
static void tcc_CollectionChanged(object sender, EventArgs e)
{
Console.WriteLine(DateTime.Now.ToString() + ", Collection changed");
return;
}
}
Corresponding XAML:
<UserControl x:Class="MuiWpfTestApp.Pages.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Loaded="UserControl_Loaded">
<Grid Style="{StaticResource ContentRoot}">
<ScrollViewer>
<DataGrid x:Name="tcgrid" ItemsSource="{Binding tcc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="250" Width="250">
<DataGridTextColumn Binding="{Binding AGNR.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Header="{Binding AGNR.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Binding="{Binding MNR.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Header="{Binding MNR.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Binding="{Binding MST.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Header="{Binding MST.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid>
</ScrollViewer>
</Grid>
INotifyPropertyChanged is implemented in TableClass:
class TableClass : INotifyPropertyChanged
{
private KeyValueClass _mnr;
private KeyValueClass _agnr;
private KeyValueClass _mst;
public KeyValueClass MNR
{
get
{
return _mnr;
}
set
{
_mnr = value;
NotifyPropertyChanged("MNR");
}
}
public KeyValueClass AGNR
{
get
{
return _agnr;
}
set
{
_agnr = value;
NotifyPropertyChanged("AGNR");
}
}
public KeyValueClass MST
{
get
{
return _mst;
}
set
{
_mst = value;
NotifyPropertyChanged("MST");
}
}
public TableClass()
{
MNR = new KeyValueClass();
AGNR = new KeyValueClass();
MST = new KeyValueClass();
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
And KeyValueClass is very simple (what do I need here?):
class KeyValueClass
{
private string _name;
private string _val;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public string Value
{
get
{
return _val;
}
set
{
_val = value;
}
}
}
I need this nested Properties in the Collection, because i can get those data in different languages. So I cannot code the headers of the grid.