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