【问题标题】:How to filter datagridview using treeview checkboxes如何使用树视图复选框过滤 datagridview
【发布时间】:2015-06-21 07:42:03
【问题描述】:

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

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

我的代码我试图从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();

      }

【问题讨论】:

    标签: c# winforms datagridview treeview


    【解决方案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 字符串。

        /// <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 的结果:

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

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

    【讨论】:

    • 过滤有问题。我现在使用字符串(是,否)而不是为 treeview checkboxes 子节点使用 int(11,16 和 31),并且 dv.RowFilter 没有得到结果 no moe .在我调试时:如果我调试,则无法找到列名 Yes。
    • 您必须发布代码供我查看,但根据您当前的代码,您的列名称是:AreaCode、Amount1、Amount2 和 Amount3。据我所知,您没有名为 Yes 的列名。将过滤器应用于 RowFilter 时,就像在 SQL 语句中创建 where 子句 [columnName] [operator (, =, =, etc..)] [columnValue]。供您参考,msdn.microsoft.com/en-us/library/…
    • 我已经编辑了我的问题并发布了新图片。我现在有三个不同的treeview checkboxes。因此,如果我选择 AreaCode = 16 和 Grant = Yes 和 Land = West (或更多选择),它应该过滤并显示给我。但我在逻辑和连接上遇到问题。很高兴再次获得帮助。
    • @Shar1er80.我认为我的逻辑思维已经下降:)。不幸的是,rowFilter 仅适用于 AreaCodetreeview1。另外两个treeview2 用于Granttreeview3 用于Land 呢?当treeview1 中没有第二个根节点 时,为什么还要使用else if 语句?我认为它不适用于其他(treeview1 &amp;2)的问题是它们在treeview1 方法中被调用。我的想法对吗?
    • 你是对的,所以你的逻辑思维没有下降;-)我没有意识到我们用来设置RowFilter的方法只是针对treeView1,而是一个可以分析所有树的通用方法并构建您的 rowFilter 字符串。话虽如此,else if 需要为每个单独提取出来,看起来就像第一个树视图一样
    猜你喜欢
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    相关资源
    最近更新 更多