I made datagrid based on wpf datagrid. I use recycling virtualization and after scrolling shows some cells in random order. When i changed one cell all ok, but when i scrolling to end of datagrid, return back and trying to change one cell, another one is changed.code sample below
Could you help me resolve this problem?
Collections of cells templates:
<gridColumns:CTemplateContainer
CellTemplate="{StaticResource GenericCellTemplate}"
CellEditingTemplate="{StaticResource GenericCellTemplate}"/>
<gridColumns:CTemplateContainer
Key="Comment"
CellTemplate="{StaticResource GenericCellTemplate}"
CellEditingTemplate="{StaticResource CellEditTemplate}"/>
<gridColumns:CTemplateContainer
Key="Checked"
CellTemplate="{StaticResource GenericCellCheckedTemplate}"
CellEditingTemplate="{StaticResource GenericCellCheckedTemplate}"/>
</gridColumns:ContainerCollection>
</grid:DataGridExtended.TemplateContainers>
Templates:
<TextBlock Text="{Binding Path=Value, Mode=TwoWay}" >
<TextBlock.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource stlTextDefaultBinding}">
</Style>
</TextBlock.Resources>
</TextBlock>
</Border>
</DataTemplate>
<DataTemplate x:Key="CellEditTemplate">
<TextBox Focusable="True" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
DataContext="{TemplateBinding DataContext}"
Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True,
NotifyOnValidationError=True}"
Tag="{TemplateBinding Tag}" BorderThickness="0" Padding="0">
</TextBox>
</DataTemplate>
Column code
`class CDataGridTemplateColumn : ctrWPF.DataGridTemplateColumn { private Binding ItemContentBinding;
public CDataGridTemplateColumn(object header, string path, CTemplateContainer container)
{
Header = header;
var binding = new Binding();
binding.Path = new PropertyPath("Cells[" + path + "]");
Binding = binding;
FillTemplates(container);
}
public CDataGridTemplateColumn(ctrWPF.DataGridColumn col, string path, CTemplateContainer container)
{
try
{
var binding = new Binding() { Mode = BindingMode.TwoWay };
binding.Path = new PropertyPath(path);
Binding = binding;
FillTemplates(container);
CGridColumnHelper.InitBaseColumn(this, col);
}
catch (Exception ex)
{ }
}
private void FillTemplates(CTemplateContainer container)
{
CellTemplate = container.CellTemplate;
CellEditingTemplate = container.CellEditingTemplate;
CellEditingTemplateSelector = container.TemplateSelector;
if (container.CellStyle == null)
return;
CellStyle = container.CellStyle;
}
public void InitBinding()
{
if (BindingColumn == null)
throw new ArgumentNullException("BindingColumn null");
ItemContentBinding = new ctrWPFData.Binding("Cells[" + BindingColumn.Index + "].Value");
}
#region Binding
private BindingBase _binding;
protected virtual void OnBindingChanged(BindingBase oldBinding, BindingBase newBinding)
{
base.NotifyPropertyChanged("Binding");
}
public virtual BindingBase Binding
{
get
{
return this._binding;
}
set
{
if (this._binding != value)
{
BindingBase oldBinding = this._binding;
this._binding = value;
base.SortMemberPath = ((Binding)value).Path.Path + ".Value";
this.ClipboardContentBinding = new Binding(((Binding)value).Path.Path + ".Value");
base.CoerceValue(DataGridColumn.SortMemberPathProperty);
this.OnBindingChanged(oldBinding, this._binding);
}
}
}
private void InitValidation(BindingBase binding)
{
Binding _bind = binding as Binding;
if (_bind == null)
return;
_bind.NotifyOnValidationError = true;
_bind.ValidatesOnDataErrors = true;
_bind.ValidatesOnNotifyDataErrors = true;
}
public override BindingBase ClipboardContentBinding
{
get
{
return (base.ClipboardContentBinding ?? this.Binding);
}
set
{
base.ClipboardContentBinding = value;
}
}
private DataTemplate ChooseCellTemplate(bool isEditing)
{
DataTemplate template = null;
if (isEditing)
{
template = this.CellEditingTemplate;
}
if (template == null)
{
template = this.CellTemplate;
}
return template;
}
private DataTemplateSelector ChooseCellTemplateSelector(bool isEditing)
{
DataTemplateSelector templateSelector = null;
if (isEditing)
{
templateSelector = this.CellEditingTemplateSelector;
}
if (templateSelector == null)
{
templateSelector = this.CellTemplateSelector;
}
return templateSelector;
}
protected override FrameworkElement GenerateEditingElement(System.Windows.Controls.DataGridCell cell, object dataItem)
{
return this.LoadTemplateContent(true, dataItem, cell);
}
protected override FrameworkElement GenerateElement(System.Windows.Controls.DataGridCell cell, object dataItem)
{
return this.LoadTemplateContent(false, dataItem, cell);
}
private void ApplyBinding(DependencyObject target, DependencyProperty property)
{
BindingBase binding = this.Binding;
if (binding != null)
{
BindingOperations.SetBinding(target, property, binding);
}
else
{
BindingOperations.SetBinding(target, property, new Binding());
}
}
private FrameworkElement LoadTemplateContent(bool isEditing, object dataItem, System.Windows.Controls.DataGridCell cell)
{
DataTemplate template = this.ChooseCellTemplate(isEditing);
DataTemplateSelector templateSelector = this.ChooseCellTemplateSelector(isEditing);
if ((template == null) && (templateSelector == null))
{
return null;
}
ContentPresenter contentPresenter = new ContentPresenter();
this.ApplyBinding(contentPresenter, ContentPresenter.ContentProperty);
contentPresenter.ContentTemplate = template;
contentPresenter.ContentTemplateSelector = templateSelector;
contentPresenter.Name = "TEST";
return contentPresenter;
}
#endregion
}
`