我基于wpf datagrid创建了datagrid。 我使用回收虚拟化,滚动后以随机顺序显示一些单元格。 当我更改一个单元格时,所有确定,但是当我滚动到datagrid的结尾时,返回并尝试更改一个单元格,另一个单元格被更改。下面的示例
你能帮我解决这个问题吗?
单元格模板的集合:
<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>
模板:
<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>
`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
}
`
答案 0 :(得分:0)
我知道此线程很旧,您现在可能已经找到了答案,但是它可以帮助其他人。 创建自定义可过滤数据网格并更改虚拟化模式(在xaml中,在datagrid属性中)修复该问题时,我遇到了同样的问题。
VirtualizingStackPanel.VirtualizationMode="Standard"
这里发生的事情是默认值(回收)将重用容器,并且在某些情况下,绑定无法更新UI。进入标准虚拟化模式将强制重新生成单元。 (它会对性能产生影响)。
有关更多详细信息,请参见此链接:VirtualizationMode