[WPF Custom Control Library] sorting, filtering and highlighting

1. How to make content easier to find a list of

Suppose there is such a list (data source locally), as much content to find one of these desired data can be difficult. To optimize this list, nothing more than sorting, filtering and highlighting.

The results of transformation of the above.

2. Sort

In WPF There are many functions to achieve the sort of data, for example Linq, but such a scenario is standard practice to use the CollectionViewSource .

CollectionViewSourceIt is a proxy class to a data set. It has two very important properties:

  • Source is a set of data sources;

  • View is a view of the data processed.

It looks and feels much like the database is not a relationship of Table View, and?

In this example use CollectionViewSourcesort code is as follows:

private readonly CollectionViewSource _viewSource;

public HighlightSample()
{
    InitializeComponent();
    _viewSource = new CollectionViewSource
    {
        Source = Employee.AllExecutives
    };

    _viewSource.View.Culture = new System.Globalization.CultureInfo("zh-CN");
    _viewSource.View.SortDescriptions.Add(new SortDescription(nameof(Employee.FirstName), ListSortDirection.Ascending));
    EmployeeElement.ItemsSource = _viewSource.View;
}

This code is CollectionViewSourcethe Source assignment to CollectionViewSourcethe ListBox View as data source. Wherein SortDescriptions for describing View sorted. If you include the Chinese, do not forget to Cultureset zh-cn.

At this point sort of function is realized. Document also mentions CollectionViewSourceother information:

You can view the collection as a binding source collection that can be used to navigate and display the collection based sorting, filtering and grouping query without the operation of all the top-level underlying source collection itself. If Source implementation INotifyCollectionChanged interface changes caused CollectionChanged event spread to View.

Because View does not change the Source, so each can have multiple associations Source of View. Use View, you may display the same data in different ways. For example, it may be desirable to display the sort of task priority in the left side of the page, and displays the tasks grouped by region on the right page.

3. Screening

CollectionViewSourceThe View attribute type ICollectionView interface, which provides a Filter property data for implementing filtering. In this example, to achieve the following:

_viewSource.View.Filter = (obj) => (obj as Employee).DisplayName.ToLower().Contains(FilterElement.Text);

private void OnFilterTextChanged(object sender, TextChangedEventArgs e)
{
    if (_viewSource != null)
        _viewSource.View.Refresh();
}

This code implements refresh View when the text input box to change the function. Where the Refresh method is used to re-create the View, that is, refresh the view.

ICollectionViewAlso provides a DeferRefresh function that is used to enter a delay loop, which can be used to view and change the delay incorporated into the auto-refresh, and the refresh operation may require multiple use this function to set a large amount of data.

4. Highlight

<TextBox x:Name="FilterElement"
         TextChanged="OnFilterTextChanged"/>
<ListBox Name="EmployeeElement"
         Grid.Row="1"
         Height="200"
         Margin="0,8,0,0">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding DisplayName}"
                           kino:TextBlockService.HighlightText="{Binding ElementName=FilterElement,Path=Text}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Highlight UWP can use TextHighlighter this class, it is simple to implement. The WPF highlight is the use of TextBlockService.HighlightTextan additional attribute declaration to highlight the text, and then replace the TextBlock Text treated Inlines, use as above.

private static void MarkHighlight(TextBlock target, string highlightText)
{
    var text = target.Text;
    target.Inlines.Clear();
    if (string.IsNullOrWhiteSpace(text))
        return;

    if (string.IsNullOrWhiteSpace(highlightText))
    {
        target.Inlines.Add(new Run { Text = text });
        return;
    }

    while (text.Length > 0)
    {
        var runText = string.Empty;
        var index = text.IndexOf(highlightText, StringComparison.InvariantCultureIgnoreCase);
        if (index > 0)
        {
            runText = text.Substring(0, index);
            target.Inlines.Add(new Run { Text = runText, Foreground = _noHighlightBrush });
        }
        else if (index == 0)
        {
            runText = text.Substring(0, highlightText.Length);
            target.Inlines.Add(new Run { Text = runText });
        }
        else if (index == -1)
        {
            runText = text;
            target.Inlines.Add(new Run { Text = runText, Foreground = _noHighlightBrush });
        }

        text = text.Substring(runText.Length);
    }
}

This is the implementation code. In fact, with the Regex.Splitcode will be a lot of good-looking, but too lazy to change the.
Was supposed to be the highlight matching text, but the actual use did not find the matching text is grayed out and look better, it is so true.

5 Conclusion

This article describes the use of CollectionViewSourcethe sort of realization, filtering capabilities and the use of additional properties and Inlinesachieve highlighting.

But this realization highlighting there is a problem: You can not define the highlight (or low light) color, whether in code or in XAML. One possible approach is to define a reference ToolTipService lot of additional attributes, such as this:

<TextBox x:Name="FilterElement" 
         ToolTipService.ToolTip="Filter Text"
         ToolTipService.HorizontalOffset="10"
         ToolTipService.VerticalOffset="10"
         TextChanged="OnFilterTextChanged"/>

The disadvantage of this approach is that it can cause a lot of additional property code becomes very complex and difficult to maintain. ToolTip ToolTipService can also create a class, the class to the value of the additional properties:

<TextBox x:Name="FilterElement" 
         TextChanged="OnFilterTextChanged">
    <ToolTipService.ToolTip>
        <ToolTip Content="Filter Text"
                 HorizontalOffset="10" 
                 VerticalOffset="10"/>
    </ToolTipService.ToolTip>
</TextBox>

This way is easier to maintain, but some people may not understand the ToolTipService.ToolTipvalue of a property can be either why the text (such as pictures or other content), and can be ToolTip types, how to identify XAML. On this point the next article I will explain, and reimplement highlighting functionality to support features such as Style.

See also SearchableTextBlock write a highlighted text box, once and for all, but I hope that through this interesting features multi introduce several knowledge.

6. References

CollectionViewSource Class (System.Windows.Data) Microsoft Docs

TextBlock.Inlines Property (System.Windows.Controls) Microsoft Docs

A WPF Searchable TextBlock Control with Highlighting WPF

7. Source

TextBlockService.cs at master

Guess you like

Origin www.cnblogs.com/dino623/p/sort_filter_highlight.html
Recommended