2016-07-08 18 views
0

Kurzer Hintergrund zum Problem: Ich arbeite an der UI Teil einer WPF-Anwendung. Aber da ich meinen Teil ziemlich schnell beendet habe - entschied ich mich, die ListBox-Filterfunktion zu implementieren.Echtzeit-Filterung der ListBox

Was ich an dieser Stelle haben:

<TextBox Style="{StaticResource WaterMarkMessageTextBoxStyle}" 
      x:Name="usuariosDisponiblesSearch" 
      Grid.Column="1" Grid.Row="1"/> 
    <ListBox Style="{StaticResource ListBoxTable}" 
      ItemContainerStyle="{StaticResource AlternatingListViewItemStyle}"     
      AlternationCount="2" 
      Grid.Column="1" Grid.Row="2" 
      x:Name="lbPossibleContracts" 
      SelectionChanged="lbPossibleContracts_SelectionChanged" > 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding Path=Nombre}" /> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

TextBox enthält eine Suchzeichenfolge. ListBox - gibt Daten wieder, die aus dem DB nach Feld Nombre ausgewählt wurden.

Am Endpunkt - Ich möchte funktionierende Filter haben, die in der ListBox nur die Elemente anzeigen, die mit der Zeichenfolge in der TextBox übereinstimmen. Echtzeit.

Natürlich verstehe ich, dass es unmöglich ist, zu tun, ohne den Back-Code zu ändern.

Das Problem ist, dass meine Ansätze zur Implementierung der Filterfunktion bisher nicht erfolgreich waren, hauptsächlich weil ich nicht verstand, was genau ich in den Backcode implementiere.

Jede Hilfe zu diesem wird geschätzt. Funktioniert in jede Richtung - wenn Sie den ganzen Teil des Codes erzeugen wollen (:)) - Sie sind willkommen, wenn Sie einen guten, verständlichen Hinweis auf ein gleiches, gelöstes Problem haben - es ist auch großartig.

UPDATE

Ok, ich habe ein paar ziemlich große Fortschritte in diesem Thema gemacht.

Ich wurde im Anschluss an dieses Beispiel: http://www.wpf-tutorial.com/listview-control/listview-filtering/

Hier sind die Codes:

 <TextBox Style="{StaticResource WaterMarkMessageTextBoxStyle}" 
      x:Name="usuariosDisponiblesSearch" 
      Grid.Column="1" Grid.Row="1" 
      TextChanged="usuariosDisponiblesSearch_TextChanged" /> 
     <ListBox Style="{StaticResource ListBoxTable}" 
       ItemContainerStyle="{StaticResource AlternatingListViewItemStyle}" 
       AlternationCount="2" 
       Margin="0,20,0,0" 
       x:Name="lbPossibleContractsFilter" 
       SelectionChanged="lbPossibleContracts_SelectionChanged" > 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock Text="{Binding Path=Nombre}" /> 
        </StackPanel> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 

Und hier ist der backcode:

public partial class ProjectAssignUsuariosView : UserControl 
{ 
    private ProjectAssignUsuariosViewModel _viewModel; 



    public ProjectAssignUsuariosView(Proyecto proyecto) 
    { 
     InitializeComponent(); 

     _viewModel = new ProjectAssignUsuariosViewModel(proyecto); 

     //TempFilterPart 
     lbPossibleContractsFilter.ItemsSource = _viewModel.UsuariosLibres; 
     List<Usuario> items = new List<Usuario>(); 
     filteredUsers.ItemsSource = items; 
     CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lbPossibleContractsFilter.ItemsSource); 
     view.Filter = UserFilter; 
     //Filtering part ends 
    } 

    //Filtering 
    private bool UserFilter(object item) 
    { 
     if (String.IsNullOrEmpty(usuariosDisponiblesSearch.Text)) 
      return true; 
     else 
      return ((item as Usuario).Nombre.IndexOf(usuariosDisponiblesSearch.Text, StringComparison.OrdinalIgnoreCase) >= 0); 
    } 


    private void usuariosDisponiblesSearch_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     CollectionViewSource.GetDefaultView(lbPossibleContractsFilter.ItemsSource).Refresh(); 
    } 
    //Filtering ends 

Keine Fehler beim Kompilieren. Aber beim Ausführen und Ändern der TextBox - Unerwarteter Anwendungsfehler. Und der Debugger sagt "NullReferenceException wurde von Benutzercode nicht behandelt. Zusätzliche Informationen: Objektreferenz nicht auf eine Instanz eines Objekts festgelegt."

+3

Versuchen Sie SO für die Filterung mit CollectionViewSource –

+0

Sounds wie ein guter Start! Kurze Frage - Was steht hinter SO? Vielen Dank im Voraus! –

+1

Diese Seite, stackoverflow –

Antwort

0

Ok, ich habe einen stabil arbeitenden Prototyp für den beschriebenen Zweck gemacht. Ich folgte diesem Beispiel: http://www.wpf-tutorial.com/listview-control/listview-filtering/ Der einzige Unterschied ist, dass meine ItemsSource außerhalb platziert wurde.

Hier sind die Arbeitscodes (vereinfacht).

XAML:

<ListBox Style="{StaticResource ListBoxTable}" 
      ItemContainerStyle="{StaticResource AlternatingListViewItemStyle}"     
      AlternationCount="2" 
      Grid.Column="1" Grid.Row="2" 
      x:Name="lbPossibleContracts" 
      SelectionChanged="lbPossibleContracts_SelectionChanged" > 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding Path=Nombre}" /> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

Wichtige Teile sind hier die ListBox x: Name-Eigenschaft, die den Zugang zum Itemssource gibt. Und ListBox SelectionChanged Property, das zur Aktualisierung der Ergebnisse aufruft.

XAML.CS:

namespace Todiste.Views.Proyectos 
{ 
public partial class ProjectAssignUsuariosView : UserControl 
{ 
    private ProjectAssignUsuariosViewModel _viewModel; 
    public ProjectAssignUsuariosView(Proyecto proyecto) 
    { 
     InitializeComponent(); 

     _viewModel = new ProjectAssignUsuariosViewModel(proyecto); 

     lbCurrentContracts.ItemsSource = _viewModel.UsuariosProyecto; 
     lbPossibleContracts.ItemsSource = _viewModel.UsuariosLibres; 
     //Filter Starts    
     CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lbPossibleContracts.ItemsSource); 
     view.Filter = UserFilter; 
     //Filter Ends 
    } 

    //Filter Starts 
    private bool UserFilter(object item) 
    { 
     if (string.IsNullOrEmpty(filter.Text)) 
      return true; 
     else 
      return ((item as Usuario).Nombre.IndexOf(filter.Text, StringComparison.OrdinalIgnoreCase) >= 0); 
    } 

    private void filter_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     CollectionViewSource.GetDefaultView(lbPossibleContracts.ItemsSource).Refresh(); 
    } 
    // Filter Ends 

Hier sind drei Punkte verdient Aufmerksamkeit:

  1. lbPossibleContracts.ItemsSource = _viewModel.UsuariosLibres; - Zuweisung außerhalb Datenquelle zur Liste
  2. Sammlung view = - definiert, die Ansicht
  3. userfilter und filter_TextChanged - tatsächlich die Funktionen sind, die Filterung und die Liste durchführen erfrischende Aktionen

nicht die beste Art, aber ein arbeitender.

Verwandte Themen