简体   繁体   中英

Filtering WPF TreeView without using Observable Collection

I am filling my TreeView from MySQL database. So I don't have classes for each of them. I use HierarchicalDataTemplate s to construct TreeView and I have three levels. I want to filter the first levels comparing the included TextBlock 's Text and user input. How can I filter without using ObservableCollection ? (I tried to use ICollectionView , but I failed.)

Source = CollectionViewSource.GetDefaultView(FileTreeView.ItemsSource);

        this.Source.Filter = item =>
            {
                TreeViewItem vitem = item as TreeViewItem;

                if (vitem == null) return false;

                foreach (object items in vitem.Items)
                {
                    vitem.ApplyTemplate();

                    TreeViewItem firstlevel = vitem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;

                    UIElement element = GetChildControl(firstlevel, "fem_title");

                    if (element != null)
                    {
                        TextBlock txt = (TextBlock)element;

                        return (txt.Text.Contains(title.SelectedValue.ToString()));
                    }
                }

                return false;

It throws an "NotSupportedException".

How I populate the TreeView:

private DataSet FillDataGrid()

    {

        try

        {

            MySqlConnection con = new MySqlConnection();

            con.ConnectionString = ConString;

            con.Open();



            MySqlDataAdapter femda = new MySqlDataAdapter("SELECT * FROM fem_table", con);

            MySqlDataAdapter versionda = new MySqlDataAdapter("SELECT * FROM version_table", con);

            MySqlDataAdapter fileda = new MySqlDataAdapter("SELECT * FROM file_table", con);



            DataSet ds = new DataSet();

            femda.Fill(ds, "fem_table");

            versionda.Fill(ds, "version_table");

            fileda.Fill(ds, "file_table");



            DataRelation dr = new DataRelation("DataRelationship_fem_version",

                ds.Tables["fem_table"].Columns["fem_guid"],

                ds.Tables["version_table"].Columns["fem_table_fem_guid"],

                true);



            DataRelation dr2 = new DataRelation("DataRelationship_version_file",

                ds.Tables["version_table"].Columns["version_id"],

                ds.Tables["file_table"].Columns["version_table_version_id"],

                true);



            dr.Nested = true;

            ds.Relations.Add(dr);

            ds.Relations.Add(dr2);

            return ds;



        }

        catch (Exception ex)

        { throw new Exception(ex.Message); }

    }



  private void Window_Loaded(object sender, RoutedEventArgs e)

    {

        this.FileTreeView.DataContext = FillDataGrid();

     }

Filter works with underlying data, not with UIElements. Since you don't use classes to represent TreeViewItem and populate them just with string, then your item is actually a string. This works:

public partial class MainWindow : Window
{
    public List<string> Test = new List<string>() { "test", "someothertext" };
    public MainWindow()
    {
        InitializeComponent();
        treeView.ItemsSource = Test;
        var Source = CollectionViewSource.GetDefaultView(treeView.ItemsSource);
        string search_text = "test";
        Source.Filter = item =>
        {
            return item.ToString().Contains(search_text);
        };
    }
}

I didn't understand if you use multiple textboxes to filter, but if you dont you should just give a name to one and use its text like

string search_text = txtbox.Text;

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