[英]Persist or reapply DataGrid.CellStyle after ICollectionView.Refresh()
我正在使用ICollectionView
作为DataGrid
ItemsSource
。 使用Style
,我突出显示了包含特定SearchString
DataGrid
单元格。 同时,我想过滤DataGrid
以显示那些包含至少一个与我的搜索匹配的单元格的行。
为了使ICollectionView.Filter
能够影响DataGrid
显示的数据,我需要调用ICollectionView.Refresh()
,这显然清除了单元格的样式,因为整个数据都已重新加载并显示为新的。
在ICollectionView.Refresh()
之后保留(或重新应用)单元格样式的方法是什么?
这是我用来设置单元格样式的代码:
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ContainsStringToBooleanConverter}">
<Binding Path="Content" RelativeSource="{RelativeSource Self}"/>
<Binding Path="DataContext.SearchString" RelativeSource="{RelativeSource AncestorType={x:Type Window}}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
这是我过滤ICollectionView
:
ItemView = CollectionViewSource.GetDefaultView(myItemChildren);
ItemView.Filter = ItemViewFilter;
...
private bool ItemViewFilter(object o)
{
if (String.IsNullOrWhiteSpace(SearchString)) return true;
var item = (o as Item);
if (item == null) return true;
bool result = (item.ItemText.ToLower().Contains(SearchString.ToLower()));
return result;
}
每次更新SearchString
都会调用Refresh()
:
public string SearchString
{
get
{
return mySearchString;
}
set
{
mySearchString = value;
ItemView.Refresh();
OnPropertyChanged("SearchString");
}
}
编辑:在mm8的注释之后,我看了一下IMultiValueConverter
。 似乎在Refresh
之后调用转换器时,所有单元格都不包含任何文本。 这是我的转换器:
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length != 2) return false;
if (values[0] == null || values[1] == null) return false;
string text = "";
if (values[0].GetType() == typeof(TextBlock))
{
// The TextBlock never contains any Text after a Refresh
text = ((TextBlock)values[0]).Text;
}
string search = values[1] as string;
if (text == null || search == null) return false;
if (String.IsNullOrWhiteSpace(text) || String.IsNullOrWhiteSpace(search)) return false;
return text.ToLower().Contains(search.ToLower());
}
我从“过滤器和样式”方法切换为突出显示单元格并仅显示包含此类突出显示的单元格的行,而改为仅样式设置。
我添加了一个额外的DataGrid.RowStyle
来隐藏不包含搜索字符串的行:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ContainsStringToBooleanConverter}">
<Binding Path="." RelativeSource="{RelativeSource Self}"/>
<Binding Path="DataContext.SearchString" RelativeSource="{RelativeSource AncestorType={x:Type Window}}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
这工作得很好,我觉得它甚至可能比过滤器方法快一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.