繁体   English   中英

在ICollectionView.Refresh()之后坚持或重新应用DataGrid.CellStyle

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM