【问题标题】:c# using advanced datagridview (ADGV) filter without BindingSourcec# 使用没有 BindingSource 的高级 datagridview (ADGV) 过滤器
【发布时间】:2019-03-13 13:06:59
【问题描述】:

我正在使用 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 的过滤和排序?

【问题讨论】:

    标签: c# datagridview filtering


    【解决方案1】:

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

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

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

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

    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 类。

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

    这是你需要添加的代码:

    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
    

    【讨论】:

    • 我怀疑你是对的,我会尝试检查代码。谢谢
    • 嘿@Tima。只是为了让您知道我已将上面的“FilterStringconverter”代码更新为我的最新版本(只是一些小调整)
    • 我收到未定义“DataPointGridViewModel”的错误。我可以知道需要做什么吗?
    • 嗨@Programmer。作为参考,我在这里有一个工作版本:github.com/OceanAirdrop/AdvancedDataGridViewDataModel - DataPointGridviewModel 将只是您想要显示的数据..
    • DataPointGridViewModel 那到底是什么?
    【解决方案2】:
        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();
        }
    

    【讨论】:

    • 欢迎来到 SO,请避免发布仅代码的答案,并为您的代码提供一些解释以获得更多说明。仅代码的答案不能被视为可接受的答案。
    【解决方案3】:

    下面是我的过滤高级数据网格的代码示例

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

    并清除过滤器

    dg.CleanFilter();
    

    【讨论】:

    • 这是做什么的?您可能需要在回答中提供更多详细信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    相关资源
    最近更新 更多