2014-09-04 1 views
2

Ceci est un deux-parter. En premier lieu, dans WPF, le contrôle ListBox standard prend automatiquement en charge la recherche en ligne de ses éléments. Il le fait en utilisant la fonction ToString des éléments, ce qui signifie que si vous avez le focus dans une listbox et que vous commencez simplement à taper, il effectuera la recherche la plus à gauche, en mettant en surbrillance les éléments dont ToString correspond à ce que vous avez tapé. Les touches suivantes dans un court laps de temps s'ajoutent à la chaîne de recherche (c.-à-d. 'A' suivi de 'S') et 'A' de gauche, alors que 'A' marque une pause, puis 'S'Comment implémentez-vous la recherche en ligne personnalisée dans un ItemsControl?

Le problème est que ce mécanisme semble dépendre uniquement de la valeur retournée par ToString, ce qui dans certains cas est quelque chose sur lequel nous ne pouvons pas nous appuyer.

La deuxième partie de ceci est que le comportement semble seulement être présent dans un ListBox, mais aucun autre objet ItemsControl (ou hiérarchique comme un TreeView.) Sans avoir à réécrire cette fonctionnalité à partir de zéro, y at-il un moyen facile de l'ajouter à un ItemsControl?

+0

Je dirais que non. 'ListBox'es contiennent le plus souvent du texte, de sorte que la fonctionnalité est logique, mais' ItemsControl' est généralement censé contenir des objets et donc la fonctionnalité de recherche par défaut dans 'ItemsControl' est moins logique. Vous avez juste besoin de faire un filtrage de base de vos données ... il devrait prendre plus de 10 lignes de code ou plus, donc ce n'est pas difficile. – Sheridan

+0

Qu'en est-il de la première partie de ma question ... qui aiderait à aborder la deuxième partie. Et votre réponse ignore complètement les modèles de données qui sont régulièrement utilisés avec ListBoxes. Même l'utilisation de DisplayMember crée implicitement un modèle de données désynchronisé avec ToString rendant cette fonctionnalité potentiellement inutile, sans parler de la confusion avec un utilisateur qui obtient un comportement de sélection impaire (sans filtrage) et qui ne sait pas pourquoi. – MarqueIV

Répondre

5

Vous pouvez contrôler ce qui est recherché avec les propriétés attachées TextSearch.Text ou TextSearch.TextPath. (Voir http://msdn.microsoft.com/en-us/library/system.windows.controls.textsearch(v=vs.110).aspx)

Vous pouvez appliquer TextSearch.TextPath à votre ListBox instance (donc il recherche cette propriété au lieu de ToString) ou vous pouvez appliquer TextSearch.Text à personne enfant ListBoxItem (vous pouvez donc définir un texte de recherche individuelle pour les éléments individuels).

<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 [email protected]}" /> <Run Text="{Binding [email protected]}" /> 
        </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> 

Ce comportement est mis en œuvre dans la classe ItemsControl (et vous pouvez trouver d'autres exemples de ItemsControl descendants à la recherche: ComboBox, DataGrid). Vous pouvez définir la propriété IsTextSearchEnabled sur true pour que cela fonctionne. (Voir http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.istextsearchenabled(v=vs.110).aspx)

La recherche de niveau unique fonctionne pour TreeView. Je pense que vous devez implémenter la recherche par programme si vous voulez effectuer une recherche à plusieurs niveaux. (Voir http://social.msdn.microsoft.com/Forums/vstudio/en-US/e6d58fcc-4eaa-4bdc-8621-ce24c8efd330/treeview-textsearch)

Questions connexes