I have created VM classes for the DataGrid items (Rows and Cells).
The VM class for Cell is shown below:
public class ListGridCell : INotifyPropertyChanged
{
public ListGridCell(string Name)
{
// Init properties
this.Name = Name;
this.DataValue = null;
this.DataEditor = null;
}
public string Name { get; private set; }
private object _DataValue;
public object DataValue
{
get { return _DataValue; }
set { _DataValue = value; NotifyPropertyChanged("DataValue"); }
}
private FrameworkElement _DataEditor;
public FrameworkElement DataEditor
{
get { return _DataEditor; }
set { _DataEditor = value; NotifyPropertyChanged("DataEditor"); }
}
...
}
DataGrid columns and VM is built totally dynamically from code.
I create template column (DataGridTemplateColumn) and set the CellTemplate to the followind template (illustrated through XAML):
<StackPanel>
<TextBlock Text="{Binding Path=DataValue}" />
<ContentControl Content="{Binding Path=DataEditor}" />
</StackPanel>
Everything works fine and as expected when DataGrid is initially filled and shown.
Now, If I try to SCROLL the grid the following exception occurs:
Specified element is already the logical child of another element. Disconnect it first.
This exception has something to do with grid's row virtualization and binding Content to DataEditor inside cell template. If I turn off the row virtualization, everything works fine but grid performance becomes very bad so it is not an option.
Do you know DataGrid virtualization works behind the scenes, what happens when row is loaded/unloaded and what could be causing this error?
Are there any workarounds?
Note: I cannot use ContentTemplate binding for cell data editor in cell template (which is suggested in many places as workaround) because I MUST manually create and initialize this cell editor.