具有循环虚拟化功能的C#WPF Datagrid
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有循环虚拟化功能的C#WPF Datagrid相关的知识,希望对你有一定的参考价值。
我基于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{私人绑定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
}
`
答案
我知道这个线程已经很老了,您现在可能已经找到了答案,但是它可以帮助其他人。创建自定义可过滤数据网格并更改虚拟化模式(在xaml中,在datagrid属性中)时,我遇到了同样的问题。
VirtualizingStackPanel.VirtualizationMode="Standard"
这里发生的事情是默认值(回收)会重新使用容器,在某些情况下,绑定无法更新UI。进入标准虚拟化模式将强制重新生成单元。 (它会对性能产生影响)。
请参阅此链接以获取更多详细信息:VirtualizationMode
以上是关于具有循环虚拟化功能的C#WPF Datagrid的主要内容,如果未能解决你的问题,请参考以下文章
WPF:关于ScrollViewer中嵌套Datagrid的问题
WPF Datagrid contains ComboBox while display textblock when display and combobox in editing mode(示例代