簡體   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