I have a weird bug and i need some rescue. I have a grid with several column of multiple types in WPF. One or several of these columns are DatePickers that I created through a FrameElementFactory :
FrameworkElementFactory dateFactory = new FrameworkElementFactory(typeof(DatePicker));
...
column = new DataGridTemplateColumn { CellTemplate = new DataTemplate
{ VisualTree = dateFactory } };
this._mainDatagrid.Columns.Add(column);
I have put a method to disable the DatePickers of my grid on a certain state of one of my variable:
private IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
//return the Datagrid Rows
}
public void SetChangeLockState(bool isUnlocked)
{
IEnumerable<DataGridRow> _rows = this.GetDataGridRows(this._mainDatagrid);
foreach (DataGridColumn _column in this._mainDatagrid.Columns)
{
if (_column.GetType() != typeof(DataGridTemplateColumn)) continue;
foreach (DataGridRow _row in _rows)
{
FrameworkElement frameworkElement = _column.GetCellContent(_row);
if (frameworkElement != null) frameworkElement.IsEnabled = !isUnlocked;
}
}
}
The problem is that when I am playing with the elevator of my grid, the Datepicker keep enabling and disabling for no reason. Example: All my DatePicker are enabled, I am playing with my vertical scroll bar, no problem.
All my DatePickers are Disabled, I am playing with my vertical scroll bar. 1 Datepicker will suddenly appear enable : DatePicker enabled 1
I am keeping playing with the scrollbar and another Datepicker will go enabled : DatePicker enabled 2
Have you any idea of what could happen ?
Thanks for your help.
This will be because
DataGrid.EnableRowVirtualization
defaults to true. This enables UI virtualisation, which means that UI Elements that are scrolled out of view may be disposed or reused. Thus on occasions when scrolling an item back into view a new DatePicker will be created via your factory, and of course this new DatePicker will not have existed whenSetChangeLockState
was called and thus will not be disabled.A quick fix would be to set
DataGrid.EnableRowVirtualization
to false, but this may not be very performant if you have lots of rows. A better solution would be to bind rather than set theIsEnabled
property, e.g. to a property on your Window using RelativeSource.