Hi all,
I'm fairly new at WPF, but managed to create a datagrid that basically works.. At least visually, everything looks good: I'm able to change the cell's background based on a DisplayColor property in the data source.
However, I first noticed slowdowns in the app, and it turns out that there are binding errors I can't get rid of while keeping the functionality (if I remove the binding to the background color, they go away).
The error in the XAML Binding Failures reads: "Cannot find governing FrameworkElement or FrameworkContentElement for target element." They occur twice:
upon initially displaying the grid, and the Datacontext says "null": only 1 error per bound column, so not a big deal
when scrolling rows in/out of view: quickly reaching hundreds of errors and causing slowdowns in the application eg when I replace the grid in its ContentControl by another user control.
There also seems to be a link with virtualization: if I set EnableRowVirtualization to false, the errors related to scrolling disappear. However, I still get the errors (and related delay) when I swap the content of the ContentControl this datagrid is located in (through a User Control) with another user control.
I am creating the datagrid's columns in code-behind, because I don't know upfront how many columns are required. Here the code lines that seem to be causing the issue:
storeColumns.Add(new DataGridTemplateColumn());
// create a cell template
Binding textBinding = new Binding($"ScheduleListForTheDay[{i}].DisplayText");
textBinding.Mode = BindingMode.OneWay;
// create a textblock
FrameworkElementFactory textFactory = new FrameworkElementFactory(typeof(TextBlock));
textFactory.SetBinding(TextBlock.TextProperty, textBinding);
textFactory.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
DataTemplate textTemplate = new DataTemplate(typeof(TextBlock));
textTemplate.VisualTree = textFactory;
// create a cell editing template
Binding comboBinding = new Binding($"ScheduleListForTheDay[{i}].EmployeeID");
comboBinding.Mode = BindingMode.TwoWay;
comboBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
// create a combobox
FrameworkElementFactory comboFactory = new FrameworkElementFactory(typeof(ComboBox));
comboFactory.SetValue(ComboBox.IsTextSearchEnabledProperty, true);
comboFactory.SetValue(ComboBox.ItemsSourceProperty, _availableEmployeeList);
comboFactory.SetValue(ComboBox.SelectedValuePathProperty, "EmployeeID");
comboFactory.SetValue(ComboBox.DisplayMemberPathProperty, "ShortName");
comboFactory.SetBinding(ComboBox.SelectedValueProperty, comboBinding);
comboFactory.AddHandler(LoadedEvent, new RoutedEventHandler(GridEditCombo_Loaded));
DataTemplate comboTemplate = new DataTemplate();
comboTemplate.VisualTree = comboFactory;
// Set the Templates to the Column
storeColumns[i].CellTemplate = textTemplate;
storeColumns[i].CellEditingTemplate = comboTemplate;
// prepare a style for the main cells
Style mainColsStyle = new Style(typeof(DataGridCell));
// define the background color
Setter bgColorSetter = new Setter();
bgColorSetter.Property = DataGridCell.BackgroundProperty;
SolidColorBrush bgColorBrush = new SolidColorBrush();
Binding bgColorBinding = new Binding($"ScheduleListForTheDay[{i}].DisplayColor");
// => this causes the slow down and errors
BindingOperations.SetBinding(bgColorBrush, SolidColorBrush.ColorProperty, bgColorBinding);
bgColorSetter.Value = bgColorBrush;
mainColsStyle.Setters.Add(bgColorSetter);
storeColumns[i].CellStyle = mainColsStyle;
dgSchedule.Columns.Add(storeColumns[i]);
Does anyone have an idea ? I have been struggling with this for several weeks and can't seem to find a solution.
My datagrid's data source:
public List<WorkScheduleDay> _myWorkDataSource = new List<WorkScheduleDay>();
My WorkScheduleDay class:
public string Day { get; set; }
public DateTime Date { get; set; }
public bool IsHoliday { get; set; }
public ObservableCollection<ScheduleUnit> ScheduleListForTheDay { get; set; }
... and finally the ScheduleUnit class:
public DateTime Date { get; set; }
public int StoreID { get; set; }
private int _employeeID;
public int EmployeeID
{
get { return _employeeID; }
set
{
if (_employeeID != value)
{
_employeeID = value;
// employee was changed: set confirmation status to false
ScheduleConfirmed = false;
}
}
}
private string _displayText;
public string DisplayText
{
get { return _displayText; }
set
{
if (_displayText != value)
{
_displayText = value;
RaisePropertyChanged();
}
}
}
private Color _displayColor;
[JsonIgnore]
public Color DisplayColor
{
get { return _displayColor; }
set
{
if (_displayColor != value)
{
_displayColor = value;
RaisePropertyChanged();
}
}
}
Any help would be highly appreciated !



