如何使用treeview复选框过滤datagridview

时间:2015-04-15 11:10:31

标签: c# winforms datagridview treeview

我有datagridview从数据库获取数据,而treeview checkBoxes应该用作过滤器。

我想通过选中/取消选中datagridview中的一个或多个来过滤treeview checkedboxes,并且应该在datagridview中显示所选项目,并将其与金额相关联:

enter image description here enter image description here

我的代码我'尝试将checkedboxes转换为treeview checkboxes

private void treeview1()
{

    string rowFilter = string.Empty;

    foreach (TreeNode node in treeView1.Nodes)
    {
  // root nodes to filter on,to check children nodes under each root node
        if (node.Text == "AreaCode")
        {
  // Iterate through the root node's children nodes and build filter based      on them being checked or unchecked
            foreach (TreeNode childNode in node.Nodes)
            {
                if (childNode.Checked)
                {
                    if (rowFilter.Length > 0)
                    {
                        rowFilter += " OR ";
                    }
                    rowFilter += "[AreaCode] = " + childNode.Text;
                    MessageBox.Show(rowFilter);
                }
            }
        }
 }




    // Apply rowFilter to DataView.RowFilter 

    try{
        //Check an see what's in the dgv
        DataView dv = new DataView(dt);
        dv.RowFilter = rowFilter;
        datagridview1.DataSource = dv;
        }
    catch(Exception)
        {
            MessageBox.Show("IT IS NOT WORKING");
        }


}


 private void treeview2()
{

    string rowFilter = string.Empty;

    foreach (TreeNode node in treeView1.Nodes)
    {
        // In case you add more root nodes to filter on, you'll want to check children nodes under each root node
        if (node.Text == "Grant")
        {
            // Iterate through the root node's children nodes and build your filter based on them being checked or unchecked
            foreach (TreeNode childNode in node.Nodes)
            {
                if (childNode.Checked)
                {
                    if (rowFilter.Length > 0)
                    {
                        rowFilter += " OR ";
                    }

     // Outcome is a string NOT WORKING RIGHT                   
  rowFilter += "[Grant] = " + childNode.Text; // gets the selected string but   can filter If I put = 'Yes' ist makes it static. I need to make it dynamic
                    MessageBox.Show(rowFilter);
                }
            }
        }
  }




    // Apply rowFilter to DataView.RowFilter 

    try{
        //Check an see what's in the dgv
        DataView dv = new DataView(dt);
        dv.RowFilter = rowFilter;
        datagridview1.DataSource = dv;
        }
    catch(Exception)
        {
            MessageBox.Show("IT IS NOT WORKING");
        }


}

 private void treeview3()
{

    string rowFilter = string.Empty;

    foreach (TreeNode node in treeView1.Nodes)
    {
        // In case you add more root nodes to filter on, you'll want to check children nodes under each root node
        if (node.Text == "Land")
        {
            // Iterate through the root node's children nodes and build your filter based on them being checked or unchecked
            foreach (TreeNode childNode in node.Nodes)
            {
                if (childNode.Checked)
                {
                    if (rowFilter.Length > 0)
                    {
                        rowFilter += " OR ";
                    }

    // Outcome is a string NOT WORKING RIGHT                   
    rowFilter += "[Land] = " + childNode.Text; // gets the selected string but can filter If I put = 'Mitte' ist makes it static. I need to make it dynamic
                    MessageBox.Show(rowFilter);
                }
            }
        }
    }




    // Apply rowFilter to DataView.RowFilter 

    try{
        //Check an see what's in the dgv
        DataView dv = new DataView(dt);
        dv.RowFilter = rowFilter;
        datagridview1.DataSource = dv;
        }
    catch(Exception)
        {
            MessageBox.Show("IT IS NOT WORKING");
        }


}




  private void treeViewAfterCheck_AfterCheck(object sender, TreeViewEventArgs e)
    {
        // Any node that is checked/unchecked will have all of its 
        // children nodes checked/unchecked
        if (e.Node.Nodes.Count > 0)
        {
            foreach (TreeNode childNode in e.Node.Nodes)
            {
                childNode.Checked = e.Node.Checked;
            }
        }

   treeview1();
   treeview2();
    treeview3();

      }

1 个答案:

答案 0 :(得分:1)

我正在基于我理解你想要做什么重建我的整个答案。

首先要了解的是设计。既然您现在有三个树视图,那么在应用过滤器时,您希望它们如何协同工作?你想要它们作为AND条件还是OR条件?

示例AND条件,([AreaCode] = 11 OR [AreaCode] == 16])AND([Land] ='North'OR [Land] ='East')

示例OR条件,([AreaCode] = 11 OR [AreaCode] == 16])OR([Land] ='North'OR [Land] ='East')

如果您不了解其中的差异,我建议您研究一些SQL。

现在,要完成应用于DataGridView的单个过滤器,您必须在一个方法中浏览所有树视图并构建rowFilter字符串appropriatley。

    /// <summary>
    /// All treeviews fire this event when a node's checkbox is check/unchecked
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
    {
        // Any node that is checked/unchecked will have all of its 
        // children nodes checked/unchecked
        if (e.Node.Nodes.Count > 0)
        {
            foreach (TreeNode childNode in e.Node.Nodes)
            {
                childNode.Checked = e.Node.Checked;
            }
        }

        // Now it doesn't matter which treeview we are working with, let's build the rowFilter
        // with all three treeviews
        string areaCodeRowFilter = string.Empty;

        // The order in which we use the treeviews is not important
        foreach (TreeNode node in treeView1.Nodes)
        {
            // treeView1 in this case is AreaCode
            // The foreach is going through all root nodes and we have to 
            //  traverse into the children nodes
            if (node.Nodes.Count > 0)
            {
                // Iterate through the children nodes to start building the rowFilter string
                foreach (TreeNode childNode in node.Nodes)
                {
                    if (childNode.Checked)
                    {
                        if (areaCodeRowFilter.Length > 0)
                        {
                            areaCodeRowFilter += " OR ";
                        }
                        areaCodeRowFilter += "[AreaCode] = " + childNode.Text;
                    }
                }
            }
        } // End foreach using treeView1 (AreaCode)

        // Do the same thing with the other treeViews
        // The order in which we use the treeviews is not important
        string landRowFilter = string.Empty;
        foreach (TreeNode node in treeView2.Nodes)
        {
            // Since these values are strings,
            // they have to be wrapped in single quotes.

            // Example, [Land] = 'North' OR [Land] = 'West'

            // treeView2 in this case is Land
            // The foreach is going through all root nodes and we have to 
            // traverse into the children nodes
            if (node.Nodes.Count > 0)
            {
                // Iterate through the children nodes to start building the rowFilter string
                foreach (TreeNode childNode in node.Nodes)
                {
                    if (childNode.Checked)
                    {
                        if (landRowFilter.Length > 0)
                        {
                            landRowFilter += " OR ";
                        }
                        landRowFilter += "[Land] = '" + childNode.Text + "'";
                    }
                }
            }
        } // End foreach using treeView2 (Land)

        string grantRowFilter = string.Empty;
        foreach (TreeNode node in treeView3.Nodes)
        {
            if (node.Nodes.Count > 0)
            {
                foreach (TreeNode childNode in node.Nodes)
                {
                    if (childNode.Checked)
                    {
                        if (grantRowFilter.Length > 0)
                        {
                            grantRowFilter += " OR ";
                        }
                        grantRowFilter += "[Grant] = '" + childNode.Text + "'";
                    }
                }
            }
        } // End foreach using treeView3 (Grant)

        // We have three rowFilter strings that we have to concantenate and set into the DataView.RowFilter
        // How will you use these filters as an AND or an OR?
        // I will use them as an AND.  I will also wrap each part 
        // of the rowFilter string in parenthesis.  

        string rowFilter = string.Empty;
        if (areaCodeRowFilter.Length > 0)
        {
            areaCodeRowFilter = "(" + areaCodeRowFilter + ")";
            rowFilter = areaCodeRowFilter;
        }
        if (landRowFilter.Length > 0)
        {
            landRowFilter = "(" + landRowFilter + ")";
            if (rowFilter.Length > 0)
            {
                rowFilter += " AND " + landRowFilter;
            }
            else
            {
                rowFilter = landRowFilter;
            }
        }
        if (grantRowFilter.Length > 0)
        {
            grantRowFilter = "(" + grantRowFilter + ")";
            if (rowFilter.Length > 0)
            {
                rowFilter += " AND " + grantRowFilter;
            }
            else
            {
                rowFilter = grantRowFilter;
            }
        }
        MessageBox.Show(rowFilter);

        // Take out the MessageBox.Show, I've only got it here to show you 
        // how the string looks when it's built

        // Apply rowFilter to your DataView.RowFilter
    }

MessageBox的结果:

enter image description here

我不喜欢这种方法的一件事是,如果单击根节点,将检查/取消选中所有子节点,并且将为每个事件触发此方法。但这应该完成工作。如果这满足了你想要的,我也建议你试着弄清楚如何缩短这个事件。我给你的只是基本的方法,在我看来,代码有点草率,可写得更干净。如果您试图缩短这一点,请务必获得此原件的副本,以备您需要回到工作解决方案。

我很乐意帮助你。为了变得更好,你将不得不在代码中进行大量的调试,但在开始编写代码之前,一定要确保你理解你想做什么以及你希望程序如何工作。