hussainroyal Ответов: 2

Как искать в выпадающем списке datagridview в C#, например '%%' с помощью SQL


Я использую.NET datagrid view comboxbox но я хочу автозаполнить как %% так же как sql я пробовал разные решения даже использовал привязки данных.. Он будет очень благодарен, если кто-то поможет..

Что я уже пробовал:

if (e.Control is DataGridViewComboBoxEditingControl)
            {
             
                ((ComboBox)e.Control).DropDownStyle = ComboBoxStyle.DropDownList;
                ((ComboBox)e.Control).AutoCompleteSource = AutoCompleteSource.ListItems;
                ((ComboBox)e.Control).AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;

          
            }

            if (dgvInputs.CurrentRow.Cells["colProduct"].Value != null)
            {
                tblProductSubBindingSource.Filter = " MainProduct LIKE '%" + dgvInputs.CurrentRow.Cells["colProduct"].Value.ToString() + "%'";
            }

2 Ответов

Рейтинг:
2

#realJSOP

У меня есть IsLike метод расширения, который позволяет выполнять сравнения, подобные SQL Server, включая все подстановочные знаки SQL server. Об этом говорится в этой статье:

SQLXAgent - задания для SQL Express - Часть 1 из 6[^]

Вот вам и метод:

/// <summary>
/// Determines whether this string is "like" the specified string. Performs
/// a SQL "LIKE" comparison.
/// </summary>
/// <param name="str">This string.</param>
/// <param name="like">The string to compare it against.</param>
/// <returns></returns>
public static bool IsLike(this string str, string pattern)
{
    // this code is much faster than a regular expression that performs the same comparison.
    bool isMatch          = true;
    bool isWildCardOn     = false;
    bool isCharWildCardOn = false;
    bool isCharSetOn      = false;
    bool isNotCharSetOn   = false;
    bool endOfPattern     = false;
    int  lastWildCard     = -1;
    int  patternIndex     = 0;
    char p                = '\0';
    List<char> set        = new List<char>();

    for (int i = 0; i < str.Length; i++)
    {
        char c = str[i];
        endOfPattern = (patternIndex >= pattern.Length);
        if (!endOfPattern)
        {
            p = pattern[patternIndex];
            if (!isWildCardOn && p == '%')
            {
                lastWildCard = patternIndex;
                isWildCardOn = true;
                while (patternIndex < pattern.Length && pattern[patternIndex] == '%')
                {
                    patternIndex++;
                }
                p = (patternIndex >= pattern.Length)  ? '\0' : p = pattern[patternIndex];
            }
            else if (p == '_')
            {
                isCharWildCardOn = true;
                patternIndex++;
            }
            else if (p == '[')
            {
                if (pattern[++patternIndex] == '^')
                {
                    isNotCharSetOn = true;
                    patternIndex++;
                }
                else
                {
                    isCharSetOn = true;
                }

                set.Clear();
                if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']')
                {
                    char start    = char.ToUpper(pattern[patternIndex]);
                    patternIndex += 2;
                    char end      = char.ToUpper(pattern[patternIndex]);
                    if (start <= end)
                    {
                        for (char ci = start; ci <= end; ci++)
                        {
                            set.Add(ci);
                        }
                    }
                    patternIndex++;
                }

                while (patternIndex < pattern.Length && pattern[patternIndex] != ']')
                {
                    set.Add(pattern[patternIndex]);
                    patternIndex++;
                }
                patternIndex++;
            }
        }

        if (isWildCardOn)
        {
            if (char.ToUpper(c) == char.ToUpper(p))
            {
                isWildCardOn = false;
                patternIndex++;
            }
        }
        else if (isCharWildCardOn)
        {
            isCharWildCardOn = false;
        }
        else if (isCharSetOn || isNotCharSetOn)
        {
            bool charMatch = (set.Contains(char.ToUpper(c)));
            if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch))
            {
                if (lastWildCard >= 0)
                {
                    patternIndex = lastWildCard;
                }
                else
                {
                    isMatch = false;
                    break;
                }
            }
            isNotCharSetOn = isCharSetOn = false;
        }
        else
        {
            if (char.ToUpper(c) == char.ToUpper(p))
            {
                patternIndex++;
            }
            else
            {
                if (lastWildCard >= 0)
                {
                    patternIndex = lastWildCard;
                }
                else
                {
                    isMatch = false;
                    break;
                }
            }
        }
    }
    endOfPattern = (patternIndex >= pattern.Length);

    if (isMatch && !endOfPattern)
    {
        bool isOnlyWildCards = true;
        for (int i = patternIndex; i < pattern.Length; i++)
        {
            if (pattern[i] != '%')
            {
                isOnlyWildCards = false;
                break;
            }
        }
        if (isOnlyWildCards)
        {
            endOfPattern = true;
        }
    }
    return (isMatch && endOfPattern);
}


hussainroyal

Привет, Джон, спасибо за ответ.. где я могу вызвать этот метод в событии представления datagrid?

#realJSOP

Это метод расширения строки, поэтому вы можете вызвать его для любой строки (в c#):

string mystring = "this is my string";
bool result = myString.IsLike("%is my%"); // will return true
result = mystring.IsLike("%bacon%"); // will return false
result = mystring.IsLike("THIS is MY string"); // will return true

Рейтинг:
1

Maciej Los

Если я вас хорошо понимаю, вы используете BindingSource в качестве источника данных для вашего DataGridView и хотите отфильтровать его данные.
Итак, как говорится в документации MSDN, a Объектом bindingsource.Фильтр[^] свойство использует выражения, задокументированные в объект DataColumn.Выражение[^] собственность. Один Like оператор может быть использован в этом контексте:

"ItemName LIKE '*product*'" - a'ka Linq Contains method
"ItemName LIKE '*product'" - a'ka Linq EndsWith method
"ItemName LIKE 'product*'" -a'ka Linq StartsWith method 


Примечание:
Подстановочные знаки не допускаются в середине строки. Например, 'te*xt' не допускается.


Итак, замените это:
tblProductSubBindingSource.Filter = " MainProduct LIKE '%" + dgvInputs.CurrentRow.Cells["colProduct"].Value.ToString() + "%'";

с:
tblProductSubBindingSource.Filter = string.Format(" MainProduct LIKE *{0}*", dgvInputs.CurrentRow.Cells["colProduct"].Value);



Если вы используете DataTable в качестве источника данных для DataGridView, вы можете отфильтровать его с помощью Linq to DataSet[^] запросы.

Для получения более подробной информации, пожалуйста, смотрите:
Руководство по программированию (LINQ to DataSet) | Microsoft Docs[^]
Запрос наборов данных (LINQ to DataSet) | Microsoft Docs[^]
Примеры LINQ to DataSet | Microsoft Docs[^]

DatTable dt = (DataTable)DataGridView.DataSource;
dt = dt.AsEnumerable()
    .Where(x=> x.Field<string>("ProductCode").Contains("searchedstring"))
    .CopyToDataTable();
DataGridView.DataSource = dt;

Удачи вам!