C#使用不带BindingSource的高级datagridview(ADGV)过滤器

时间:2018-10-08 20:08:29

标签: c# datagridview filtering

我正在使用here找到的高级DataGridView(ADGV)为我的应用程序添加过滤功能。

用于过滤或排序的代码被提及为:

private void advancedDataGridView1_SortStringChanged(object sender, EventArgs e)
{
    this.stockHistoryBindingSource.Sort = advancedDataGridView1.SortString;
}

private void advancedDataGridView1_FilterStringChanged(object sender, EventArgs e)
{
    this.stockHistoryBindingSource.Filter = advancedDataGridView1.FilterString;
}

但是我不能使用它,因为在我的项目中,我正在读取一个XML文件,并使用以下代码将其绑定到我的ADGV:

void QueryFoos()
{
    IEnumerable<FooViewData> query =
        from foo in XmlFiles.FOO.Root.Descendants("foo")
        select new FooViewData
        {
            ID = Convert.ToInt32(foo.Attribute("id").Value),
            Num = Convert.ToInt32(foo.Attribute("num").Value),
            ...
        };

    advancedDataGridView1.DataSource = query.OrderBy(n => n.ID).ThenBy(r => r.Num).ToList();
}

我尝试过这样的代码,但是我不惊讶它会抛出异常:

BindingSource x = (BindingSource)this.advancedDataGridView1.DataSource;
x.Filter = advancedDataGridView1.FilterString;
this.advancedDataGridView1.DataSource = x;

可以使用ADGV的过滤和排序吗?

3 个答案:

答案 0 :(得分:1)

事实证明,我今天遇到同样的问题,正在寻找解决方案。基本上,问题在于ADGV被编写为用于DataTable而不是对象列表。

顺便说一句,该项目的代码存储库现在位于github here

此解决方案对我有用,但是您的里程可能会有所不同。

我最终要做的是使用dynamic linq对自己的对象列表执行过滤。 hack的部分是我将ADGV生成的过滤器字符串转换为动态linq期望的字符串。

这是示例代码:

List<DataPointGridViewModel> m_dataGridBindingList = null;
List<DataPointGridViewModel> m_filteredList = null;

private void dataGridView2_FilterStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.FilterEventArgs e)
{
    try
    {
        if ( string.IsNullOrEmpty(dataGridView2.FilterString) == true )
        {
            m_filteredList = m_dataGridBindingList;
            dataGridView2.DataSource = m_dataGridBindingList;
        }
        else
        {
            var listfilter = FilterStringconverter(dataGridView2.FilterString);

            m_filteredList = m_filteredList.Where(listfilter).ToList();

            dataGridView2.DataSource = m_filteredList;
        }
    }
    catch (Exception ex)
    {
        Log.Error(ex, MethodBase.GetCurrentMethod().Name);
    }
}

这是将ADGV过滤器字符串转换为Dynamic Linq过滤器字符串的函数:

private string FilterStringconverter(string filter)
{
    string newColFilter = "";

    // get rid of all the parenthesis 
    filter = filter.Replace("(", "").Replace(")", "");

    // now split the string on the 'and' (each grid column)
    var colFilterList = filter.Split(new string[] { "AND" }, StringSplitOptions.None);

    string andOperator = "";

    foreach (var colFilter in colFilterList)
    {
        newColFilter += andOperator;

        // split string on the 'in'
        var temp1 = colFilter.Trim().Split(new string[] { "IN" }, StringSplitOptions.None);

        // get string between square brackets
        var colName = temp1[0].Split('[', ']')[1].Trim();

        // prepare beginning of linq statement
        newColFilter += string.Format("({0} != null && (", colName);

        string orOperator = "";

        var filterValsList = temp1[1].Split(',');

        foreach (var filterVal in filterValsList)
        {
            // remove any single quotes before testing if filter is a num or not
            var cleanFilterVal = filterVal.Replace("'", "").Trim();

            double tempNum = 0;
            if (Double.TryParse(cleanFilterVal, out tempNum))
                newColFilter += string.Format("{0} {1} = {2}", orOperator, colName, cleanFilterVal.Trim());
            else
                newColFilter += string.Format("{0} {1}.Contains('{2}')", orOperator, colName, cleanFilterVal.Trim());

            orOperator = " OR ";
        }

        newColFilter += "))";

        andOperator = " AND ";
    }

    // replace all single quotes with double quotes
    return newColFilter.Replace("'", "\"");
}

...最后,排序功能如下:

private void dataGridView2_SortStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.SortEventArgs e) 
{
    try
    {
        if (string.IsNullOrEmpty(dataGridView2.SortString) == true)
            return;

        var sortStr = dataGridView2.SortString.Replace("[", "").Replace("]", "");

        if (string.IsNullOrEmpty(dataGridView2.FilterString) == true)
        {
            // the grid is not filtered!
            m_dataGridBindingList = m_dataGridBindingList.OrderBy(sortStr).ToList();
            dataGridView2.DataSource = m_dataGridBindingList;                    
        }
        else
        {
            // the grid is filtered!
            m_filteredList = m_filteredList.OrderBy(sortStr).ToList();
            dataGridView2.DataSource = m_filteredList;
        }
    }
    catch (Exception ex)
    {
        Log.Error(ex, MethodBase.GetCurrentMethod().Name);
    }
}

最后,您将需要here

中的Dynamic Linq库

您可以使用Nuget将其引入您的项目:

Install-Package System.Linq.Dynamic

答案 1 :(得分:0)

    DataTable OrignalADGVdt = null;
    private void advancedDataGridView1_FilterStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.FilterEventArgs e)
    {
        Zuby.ADGV.AdvancedDataGridView fdgv = advancedDataGridView1;
        DataTable dt = null;
        if (OrignalADGVdt == null)
        {
            OrignalADGVdt = (DataTable)fdgv.DataSource;
        }
        if (fdgv.FilterString.Length > 0)
        {
            dt = (DataTable)fdgv.DataSource;
        }
        else//Clear Filter
        {
            dt = OrignalADGVdt;
        }

        fdgv.DataSource = dt.Select(fdgv.FilterString).CopyToDataTable();
    }

答案 2 :(得分:0)

这里按照我的代码示例过滤高级数据网格

string myFilter = "(Convert([myCol],System.String) IN ('myfilter'))"
dg.LoadFilterAndSort(myFilter, "");

并清除过滤器

dg.CleanFilter();