c# using advanced datagridview (ADGV) filter without BindingSource

前端 未结 2 885
無奈伤痛
無奈伤痛 2021-01-23 18:58

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:



        
相关标签:
2条回答
  • 2021-01-23 19:37
        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();
        }
    
    0 讨论(0)
  • 2021-01-23 19:50

    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.

    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.

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

    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.

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

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

    Finally, you will need the Dynamic Linq library from here

    You can use Nuget to bring it into your project:

    Install-Package System.Linq.Dynamic
    
    0 讨论(0)
提交回复
热议问题