Eiredrake Ответов: 1

Элемент фильтр на все столбцы


Я работаю с DataTable, содержащим объекты Skill, которые описывают навыки в larp, в который я играю. Исходные навыки берутся из базы данных nosql. Я показываю эти данные в DataGridView . По сути, я хочу иметь текстовое поле, в которое вы можете ввести фильтр, и чтобы DataGridView отображал любую строку, содержащую любое поле, содержащее ваш текст фильтра.

Так например
Name              Short Description      Tier  Category  Tags
Avoid             dodge Bullets          Basic Combat    nopes, combat
Basic Projectile  Allows use of firearms Basic Combat    combat, firearms


Используя вышеприведенные данные, если вы ввели в свой фильтр слово "огнестрельное оружие". Вы получите одну строку, содержащую "основной снаряд". Если вы наберете в бою, то получите как избегающий, так и основной снаряд (из-за категории и тегов)

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

За исключением одного поля "Теги". Базовая структура, содержащая эти теги в классе, на самом деле является списком<string>. Я форматирую его в событии CellFormatting DataGridView, и хотя список "строка" отображается правильно в DataGridView, я не могу получить ничего для фильтрации по этим тегам, даже используя CONVERT (), например, Contains и так далее. Все остальные поля работают просто отлично, но я предполагаю, что поле тегов ничего не возвращает или возвращает значение ToString() поля, и оно в конечном итоге становится системой.Коллекции.Generic.List<skill> а не список тегов.

Я люблю LINQ, но я пытаюсь сделать это через RowFilter в DefaultView DataTable, потому что я могу генерировать строку на основе пользовательского ввода.

Я видел много приложений, как настольных, так и веб-приложений, которые делают это, поэтому я знаю, что это возможно. Я просто не знаю, почему это не работает в данном случае.

Недвижимость, о которой идет речь, находится ниже (все остальные работают просто отлично). К нему подключен конвертер, но он, похоже, никогда не вызывается.
private List tags;
[TypeConverter(typeof(StringListConverter))]
public List Tags
{
    get { return this.tags; }
    set
    {
        if (value != this.tags)
        {
            this.tags = value;
            NotifyPropertyChanged();
        }
    }
}


public class StringListConverter : TypeConverter
{
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is List)
        {
            return string.Join(" ", value);
        }
        return base.ConvertFrom(context, culture, value);
    }
}


Есть ли у кого-нибудь идеи, как фильтровать свойство, содержащее список строк?

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

Метод расширения в настоящее время генерирует следующую строку:

Convert(Id, 'System.String') Like '%nope%' OR Convert(Name, 'System.String') Like '%nope%' OR Convert(Description, 'System.String') Like '%nope%' OR Convert(ShortDescription, 'System.String') Like '%nope%' OR Convert(SkillCategory, 'System.String') Like '%nope%' OR Convert(SkillTier, 'System.String') Like '%nope%' OR Convert(Tags, 'System.String') Like '%nope%'

Eiredrake

Convert должен использовать ToString() для преобразования. Если я ищу "систему", "общий" или "список", я получаю оба элемента, ни один из которых не содержит ни одного из этих терминов.

1 Ответов

Рейтинг:
1

Eiredrake

Итак... это немного халтура, и все еще не объясняет, что происходит. Но теперь я могу искать по тегам.

во-первых, я добавил свойство побочного эффекта для класса Skills, которое заставляет корректное преобразование из списка<string> В строку, разделенную запятыми..

public string TagString
        {
            get
            {
                return string.Join(", ", this.tags);
            }
        }


Затем я изменил столбец DataGridViewTextBoxColumn, чтобы он указывал на TagString вместо тегов.
this.tagsColumn             = new DataGridViewTextBoxColumn() { DataPropertyName = "TagString", HeaderText = "Tags", AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells };


затем я удалил событие CellFormatting

private void SkillListView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    //if (sender is DataGridView dataGridView)
    //{
    //    if (e.ColumnIndex == this.tagsColumn.Index)
    //    {
    //        if (e.Value is List<string> stringList)
    //        {
    //            e.Value = string.Join(", ", stringList);
    //            e.FormattingApplied = true;
    //        }
    //    }
    //}
}


теперь, если я ищу "нет", я получаю только избегание.

Однако, если я ищу "System", "Generic" или "String", я все равно получаю оба элемента.

Ну, в любом случае, это всего лишь тестовая упряжь.


Если у вас, ребята, есть еще какие-то предложения, я все равно с удовольствием их выслушаю.


Maciej Los

Это звучит не как ответ, А как вторая часть вопроса...