c # с использованием расширенного фильтра datagridview (ADGV) без BindingSource - PullRequest
0 голосов
/ 08 октября 2018

Я использую расширенный 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?

1 Ответ

0 голосов
/ 05 ноября 2018

Как оказалось, у меня была та же проблема сегодня, и я искал решения.В основном проблема в том, что ADGV был написан для использования с DataTable, а не со списком объектов.

Это решение работает для меня, однако ваш пробег может отличаться.

В итоге я использовал dynamic linq , чтобы выполнить фильтр для списка объектов самостоятельно.Хакерская часть заключалась в том, что я преобразовал строку фильтра, которую создает 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: здесь

Вот код, который вам нужно добавить:

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

Наконец, вам понадобится библиотека Dynamic Linq от здесь

Вы можете использовать Nuget, чтобы добавить ее в свой проект:

Install-Package System.Linq.Dynamic
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...