Wątek przeniesiony 2014-05-07 11:54 z C# i .NET przez somekind.

Tworzenie filtru do ListBox'a w WPF.

0

Witam, mam problem z dodanie filtru do ListBoxa w WPF. Szukałem w sieci ale żadne rozwiązania nie działają. O ile w WinForms było to proste tak tutaj nie mogę sobie poradzić. Prosiłbym o pomoc jak można to zrealizować.

0

A mi działa i wygooglałem rozwiązanie.

0

Mógłbyś się podzielić?

 {
            list = new List<string>();
            
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://test.pl);
            request.Method = WebRequestMethods.Ftp.ListDirectory;

            
            request.Credentials = new NetworkCredential("user", "password");

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();

            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            
           
            
            string line = reader.ReadLine();
      
            while (!string.IsNullOrEmpty(line))
            {

                
                line = reader.ReadLine();
                if (line != ".." && line != ".")
                {
                    list.Add(line);
                }

                
            }
            reader.Close();

            response.Close();
            lb.ItemsSource = list;

            }

W ten sposób ściągam dane do ListBoxa. I teraz w metodzie

private void search_TextChanged(object sender, TextChangedEventArgs e)
        {

            

 
        }
 

Chciałbym żeby po wpisaniu tekstu odnalazło mi text w liście.
Działa mi odnajdywanie za pomocą paramatru IsTextSearchEnabled="True" wpisanego przy tworzeniu Lstboxa ale to mnie nie urządza.

0

mi działa więc i tobie musi

http://www.wpf-tutorial.com/listview-control/listview-filtering/

EDIT:
W metodzie

 txtFilter_TextChanged

odświeżasz widok kontrolki z danymi w których szukasz.

Zasada działania jest taka, że kontrolka np. ListBox dla każdego elementu w liście sprawdza za pomocą eventu

 private bool UserFilter(object item)

czy element spełnia warunki do wyświetlenia. Jeśli tak to jest wyświetlany. Więc to w tej metodzie sprawdzasz czy element np. nazywa się tak samo jak text wpisany w textboxie. Jeśli tak to zwracasz true. Resztą zajmie się WPF, wyświetli w kontrolce pasujące texty, zmieni rozmiar kontrolki jeśli trzeba itd. Po dodaniu nowej literki do textboxa trzeba znowu odświeżyć ListBoxa czy tam Ggrida czy cokolwiek do przechowywania list.

Albo inne rozwiązanie

http://msdn.microsoft.com/pl-pl/library/ms752348(v=vs.110).aspx

A jak szukać czy text z textBoxa pasuje do tego w kontrolce ? A różnie, widziałem i LINQ i nawet RegEx lub nawet metody klasy String

0

Wczoraj już pracowałem na tym kodzie z pierwszego linku tylko nie wiem jak mam rozwiązać problem jednej linijki z metody

 
private bool UserFilter(object item
 {
 if(String.IsNullOrEmpty(txtFilter.Text))
 return true;
 else
 return ((item as User).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0);

Dokładnie chodzi o linijkę return ((item as User).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0);

Nie wiem co w moim przypadku mam użyć za (item as User) bo ja nie korzystam z klasy User w moim przypadku tylko ładuję bezpośrednio linie do listy.

0

User to jakiś typ , klasy User która przechowuje dane. Name to property tej klasy . Zobacz sam w przykładzie który ci wysłałem wyżej

        public class User
        {
                public string Name { get; set; }

                public int Age { get; set; }

                public string Mail { get; set; }

                public SexType Sex { get; set; }
        }
 

ty przechowujesz dane nie w klasie tylko w liście więc twoje odwołanie do obiektu powinno wyglądać

return ((item as list).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0); 
 

bo z kodu wyżej widzę , że dane trzymasz w liście nazwanej list

list.Add(line); 
0

Nie można zrobić
return ((item as list).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0);

Po dodaniu tam list wywala błąd, Error is a 'field' but is used like a 'type'. Potrzebowałbym rozwiązanie, które nie potrzebuje tej klasy bo w moim przypadku nie ma sensu jej tworzyć.

0
return ((item as string).IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0);
0

Sprawdzałem niestety nie działa rozwiązanie z klasą string.Wyrzuca błąd:
string' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)

Ok kompiluje się bo zapomniałem tam wyrzucić Name ale teraz mi wywala, że :Object reference not set to an instance of an object. Mimo tego, że lista jest wyświetlona,a tekst wpisuję.

0

string' does not contain a definition for 'Name' and no extension method 'Name' accepting a

Przyjrzyj się jeszcze raz mojemu poprzedniemu postowi.
Gdzie w stringu masz pole Name że chcesz się do niego odwołać?

0

Poprawiłem i jest nadal problem.

0

Jaki?

Takie coś u mnie działa. Sprawdź co masz źle.

List<string> list;
        public MainWindow()
        {
            InitializeComponent();

            list = new List<string> { "sdfasdfe", "asdfasdf", "dfe", "fasdf", "sdfe", "as", "sd", "asdfasdsadf" };
            listBox1.ItemsSource = list;
            ICollectionView view = CollectionViewSource.GetDefaultView(listBox1.ItemsSource);
            view.Filter = UserFilter;
            
            
        }
        private bool UserFilter(Object item)
        {
            if (String.IsNullOrEmpty(textBox1.Text))
                return true;
            else{
                    return ((item as string).IndexOf(textBox1.Text, StringComparison.OrdinalIgnoreCase) >= 0);
                }
        }

        private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
        {
            CollectionViewSource.GetDefaultView(listBox1.ItemsSource).Refresh();
        }
0

Może nullReferenceException ?

0

Zaraz, na początku twój textbox miał nazwę search
później używasz nazwy
txtFilter
Czy ty skopiowałeś kod żywcem z tutoriala i liczysz że zadziała?

0
        List<string> list;
        ICollectionView view;
        
        public ftp()
        {
            InitializeComponent();
            list_view();
        }
    private void list_view()
        {
        
            list = new List<string>();
            
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://.../");
            request.Method = WebRequestMethods.Ftp.ListDirectory;

            
            request.Credentials = new NetworkCredential("...", "...");

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();

            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            
           
            
            string line = reader.ReadLine();
      
            while (!string.IsNullOrEmpty(line))
            {

                
                line = reader.ReadLine();
                if (line != ".." && line != ".")
                {
                    list.Add(line);
                }

                
            }
            reader.Close();

            response.Close();
            lb.ItemsSource = list;
            view = CollectionViewSource.GetDefaultView(lb.ItemsSource);
            view.Filter = UserFilter;
          
       
        }
 private bool UserFilter(object item)
        {
            if (String.IsNullOrEmpty(search.Text))
                return true;
            else
                return ((item as string).IndexOf(search.Text, StringComparison.OrdinalIgnoreCase) >= 0);
        }
  private void search_TextChanged(object sender, TextChangedEventArgs e)
        {
            CollectionViewSource.GetDefaultView(lb.ItemsSource).Refresh();
        }

W linijce return ((item as string).IndexOf(search.Text, StringComparison.OrdinalIgnoreCase) >= 0); wyrzuca błąd, o którym kolega wyżej pisał An unhandled exception of type 'System.NullReferenceException' occurred in shop_back_end_app.exe

dodanie znacznika <code class="csharp"> - furious programming

0

To wszystko jest w tej samej klasie?
Nie mam pojęcia już.

0

Tylko dziwię się, że u Ciebie identycznie zrobiony projekt działa. A ty go robisz w WPF czy w WinForms?

0
 InitializeComponent();
            List<User> items = new List<User>();
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://f..l/");
            request.Method = WebRequestMethods.Ftp.ListDirectory;
            request.Credentials = new NetworkCredential("l...", "..");
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            string line = reader.ReadLine();
           /* while (!string.IsNullOrEmpty(line))
            {


                line = reader.ReadLine();
                if (line != ".." && line != ".")
                {
                   
                    items.Add(new User() { Name = line });
                }


            }
            reader.Close();
            response.Close();*/
           items.Add(new User() { Name = "ala"});
            items.Add(new User() { Name = "bala" });
            items.Add(new User() { Name = "zosia" });
            lvUsers.ItemsSource = items;
            CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
            view.Filter = UserFilter;

Zrobiłem identycznie jak w przykładzie i działa mi filtrowanie ale jeżeli dodam dane do listy tak jak tu:

 items.Add(new User() { Name = "ala"});
            items.Add(new User() { Name = "bala" });
            items.Add(new User() { Name = "zosia" });

A nie działa czyli jest ten błąd co wcześniej o nie wystąpieniu obiektu na jego wywołanie mimo że dane się do listy wczytują jak zrobię tak:

 while (!string.IsNullOrEmpty(line))
            {


                line = reader.ReadLine();
                if (line != ".." && line != ".")
                {
                   
                    items.Add(new User() { Name = line });
                }

Może ktoś mi powie gdzie robię błąd bo to i to jest stringiem więc nie wiem w czym problem

dodanie znaczników <code class="csharp"> - furious programming

0
string str;
                while ((str = reader.ReadLine()) != null)
                 {
                    if (str != ".." && str != ".")
                    {
                        items.Add(new User() { Name = str });
                    }
                    
                 }

DZIAŁA zmieniłem sposób wpisywania danych do listy i jest ok:) A mam jeszcze pytanie odnośnie sortowania listy w WPF? Najlepiej przy użyciu tego co aktualnie mam:)

dodanie znacznika <code class="csharp"> - furious programming

1 użytkowników online, w tym zalogowanych: 0, gości: 1