简体   繁体   中英

How do you implement custom inline searching in an ItemsControl?

This is a two-parter.

First, in WPF the standard ListBox control automatically supports inline searching of its items. It does this via using the items' ToString function, meaning if you have the focus inside a listbox and just start typing, it will do a left-most search, highlighting any items whose ToString matches what you've typed. Subsequent key presses within a short period of time add to the search string (ie typing 'A' followed by 'S' will left-search for 'AS' whereas typign 'A' then pausing, then typing 'S' will instead left-search for 'S'.

The problem is this mechanism seems to be dependent solely on the value returned by ToString, which in some cases is something we can't rely on. Is there something else we can use instead of ToString?

The second part of this is that behavior only seems to be present in a ListBox, but no other ItemsControl objects (or hierarchical ones like a TreeView.) Without having to re-write that functionality from scratch, is there an easy way to add it to an ItemsControl?

You can control what is searched with TextSearch.Text or TextSearch.TextPath attached properties. (See http://msdn.microsoft.com/en-us/library/system.windows.controls.textsearch(v=vs.110).aspx )

You can apply TextSearch.TextPath to your ListBox instance (so it searches this property instead of ToString ) or you can apply TextSearch.Text to individual ListBoxItem child (so you can set individual search text for individual elements).

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <XmlDataProvider x:Key="Items" XPath="People">
            <x:XData>
                <People xmlns="">
                    <Person Name="John" Surname="Smith" />
                    <Person Name="Andrew" Surname="Johnson" />
                    <Person Name="Otis" Surname="Everett" />
                    <Person Name="Jesus" Surname="Osborn" />
                </People>
            </x:XData>
        </XmlDataProvider>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="Searches by a property (Name):" />
        <ListBox ItemsSource="{Binding Source={StaticResource Items}, XPath=*}"
                 TextSearch.TextPath="@Name">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <Run Text="{Binding XPath=@Name}" /> <Run Text="{Binding XPath=@Surname}" />
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <TextBlock>Searches by a individual value (number in english):</TextBlock>
        <ListBox>
            <ListBoxItem TextSearch.Text="One">1</ListBoxItem>
            <ListBoxItem TextSearch.Text="Two">2</ListBoxItem>
            <ListBoxItem TextSearch.Text="Three">3</ListBoxItem>
            <ListBoxItem TextSearch.Text="Four">4</ListBoxItem>
        </ListBox>
    </StackPanel>
</Window>

This behavior is implemented in the ItemsControl class (and you can find other examples of ItemsControl descendants with search: ComboBox , DataGrid ). You can set IsTextSearchEnabled property to true to make it work. (See http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.istextsearchenabled(v=vs.110).aspx )

The single level search works for TreeView . I think you should implement the search programmatically if you want to perform multi level search. (see http://social.msdn.microsoft.com/Forums/vstudio/en-US/e6d58fcc-4eaa-4bdc-8621-ce24c8efd330/treeview-textsearch )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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