C#使用不带BindingSource的高级datagridview(ADGV)过滤器 [英] c# using advanced datagridview (ADGV) filter without BindingSource

查看:85
本文介绍了C#使用不带BindingSource的高级datagridview(ADGV)过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此处找到的高级DataGridView(ADGV)向其中添加过滤功能我的应用程序。

I am using the advanced DataGridView (ADGV) found here to add filtering capabilities to my application.

用于过滤或排序的代码如下:

The code for filtering or sorting is mentioned as:

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:

But I can't use this because in my project I am reading an XML file and binding it to my ADGV with this code:

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();
}

我尝试了这样的代码,但是它抛出异常,我并不感到惊讶在我的脸上:

I tried a code like this but I am not surprised that it is throwing exception in my face:

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

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

Is there some work around to use the filtering and sorting of the ADGV ?

推荐答案

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

As it turns out I had this same problem today and was looking for solutions. Basically the problem is that ADGV was written to be used with a DataTable and not a list of objects.

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

This solution works for me however your mileage may vary.

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

What I ended up doing was using dynamic linq to perform the filter on the list of objects myself. The hack part was me converting the filter string that ADGV produces and converting it to a string that dynamic linq expects.

我们从一些数据开始。我有一个名为DataPointGridViewModel的类,如下所示:

We start with some data. I have a class named DataPointGridViewModel that looks like this:

public class DataPointGridViewModel 
{
    public int DataPointId { get; set; }
    public string Description { get; set; }
    public bool InAlarm { get; set; }
    public DateTime LastUpdate { get; set; }
    public double ScalingMultiplier { get; set; }
    public decimal Price { get; set; }
}

数据可以是任何数据。这是您将在网格中过滤的数据。显然,您将拥有自己的数据类。您需要使用自己的模型/数据对象替换此DataPointGridViewModel类。

The data could be anything. This is the data that you will be filtering on in the grid. Obviously you will have your own data class. You need to replace this DataPointGridViewModel clas with your own model/data object.

现在,这是您需要添加的代码示例代码。我还在github上有一个示例项目:我在github上有此代码的工作版本:这里

Now, here is the code example code you need to add. I have also got a sample project on github here: I have a working version of this code on github: here

这是您需要添加的代码:

Here is the code you need to add:

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过滤字符串的函数到动态Linq过滤器字符串:

And this is the function to convert the ADGV filter string to the Dynamic Linq filter string:

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("'", "\"");
}

...最后排序功能看起来像这样:

...and finally the sort function looks like this:

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);
    }
}

最后,您将需要< a href = https://github.com/kahanu/System.Linq.Dynamic rel = nofollow noreferrer>此处

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

You can use Nuget to bring it into your project:

Install-Package System.Linq.Dynamic

这篇关于C#使用不带BindingSource的高级datagridview(ADGV)过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆