Здравствуйте, мне нужно сделать нечеткий поиск(по левенштейну). Типа вводим в текстбоксе слово(фамилию например) и сравниваем с таблицей. Нужно чтобы допустим ввел слово и показывалось сообщение(пропущена буква, есть лишняя буква, заменена буква, совпадение есть).
Вот наработки кода:
Это не наработки, а издевательство над WPF .....
Я плакать ....
Чуть позже скину как должен выглядеть View WPF для Вашего случая.
Добавлено через 2 часа 34 минуты
Пишу и делаю одновременно.
Для любого WPF решения фактически обязательным является наличие классов реализующего интерфейс INotifyPropertyChanged и ICommand. Я буду использовать две такие реализации
OnPropertyChangedClass
/// <summary>Базовый класс с реализацией INPC </summary>publicclass OnPropertyChangedClass : INotifyPropertyChanged
{#region Событие PropertyChanged и метод для его вызова/// <summary>Событие для извещения об изменения свойства</summary>publicevent PropertyChangedEventHandler PropertyChanged;/// <summary>Метод для вызова события извещения об изменении свойства</summary>/// <param name="prop">Изменившееся свойство</param>publicvoid OnPropertyChanged([CallerMemberName]string prop =""){string[] names = prop.Split("\\/\r\n()\"\'-".ToArray(), StringSplitOptions.RemoveEmptyEntries);switch(names.Length){case0:break;case1:
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));break;default:
OnPropertyChanged(names);break;}}/// <summary>Метод для вызова события извещения об изменении списка свойств</summary>/// <param name="propList">Список имён свойств</param>publicvoid OnPropertyChanged(IEnumerable<string> propList){foreach(string prop in propList.Where(name =>!string.IsNullOrWhiteSpace(name)))
OnPropertyChanged(prop);}/// <summary>Метод для вызова события извещения об изменении списка свойств</summary>/// <param name="propList">Список свойств</param>publicvoid OnPropertyChanged(IEnumerable<PropertyInfo> propList){foreach(PropertyInfo prop in propList)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop.Name));}/// <summary>Метод для вызова события извещения об изменении всех свойств</summary>/// <param name="propList">Список свойств</param>publicvoid OnAllPropertyChanged(){
OnPropertyChanged(GetType().GetProperties());}#endregion}
Добавлено через 39 минут
Для модели нам нужны методы сохранения/чтения списка слов. Метод добавления слова. Метод поиска в списке. И свойство возвращающее список слов.
Вот такая будет модель
/// <summary>Статический класс модели данных</summary>publicstaticclass FuzzySearch_Model
{static ObservableCollection<string> _listWords;/// <summary>Список слов</summary>publicstatic ObservableCollection<string> ListWords
{get=> _listWords ??(_listWords =new ObservableCollection<string>());privateset=> _listWords =value;}/// <summary>Сохранение списка слов в файле</summary>/// <param name="NameFile">Имя файла</param>publicstaticvoid Save(string NameFile =null){if(string.IsNullOrWhiteSpace(NameFile))
NameFile ="ListWords.txt";
StreamWriter file =new StreamWriter(NameFile, false, Encoding.Default);foreach(string word in ListWords)
file.WriteLine(word);
file.Close();}/// <summary>Чтение списка слов из файла</summary>/// <param name="NameFile">Имя файла</param>publicstaticvoid Load(string NameFile =null){if(string.IsNullOrWhiteSpace(NameFile))
NameFile ="ListWords.txt";
StreamReader file =new StreamReader(NameFile, Encoding.Default);
ListWords =new ObservableCollection<string>(file.ReadToEnd().Split("\r\n ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
file.Close();}/// <summary>Добавление слова в список</summary>/// <param name="Words">Слово или список слов разделённых переносом строки или пробелом</param>publicstaticvoid AddWord(string Words){foreach(string word in Words.Split("\r\n ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
ListWords.Add(word);}/// <summary>Поиск слова в списке</summary>/// <param name="Word">Одно слово</param>/// <returns>Результат поиска</returns>publicstaticstring SearchWord(string Word){string[] wordArr = Word.Split("\r\n ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);if(wordArr.Length!=1)return"Ошибка ввода";
Word = wordArr[0];int index = ListWords.IndexOf(Word);if(index >=0)return"Tочное совпадение со словом по индексу "+ index;/// *************************/// Нечёткий поиск/// *************************return"Результат нечёткого поиска";}}
Добавлено через 49 минут
Для создания View (окна) нам нужна VM времени разработки. Она будет наследоваться от класса OnPropertyChangedClass и будет базой для реальной VM.
Всё - наше WPF приложение в простейшем виде работает. Конечно, здесь многого нет. В том числе проверки на ошибки, поэтому файл "ListWords.txt" надо самому создать в папке где находится exe-файл приложения. Иначе будет исключение.
Нет реализации получения имени файла.
Так же нет реализации самого алгоритма нечёткого поиска. Он должен быть прописан в методе SearchWord модели. Но это уже не относится к WPF. В модели есть слово которое надо искать - это параметр Word, список слов в котором искать - это свойство модели ListWords и возвращать метод будет результат поиска. Но сам алгоритм поиска надо писать отдельно. Если не знаете как, то обратитесь в раздел для начинающих. Там недавно была неплохая реализация нечёткого поиска.
Добавлено через 1 минуту
Опаньки! Забыл!
Надо же подключить в Xaml реальною VM!
Элд Хасп, да, и требуем закрепить его в шапке ветки. Ну или полноценный гайд по mvvm.
я только не пойму, почему не использовать старую простую реализацию inpc и вручную писать изменившиеся свойства
C#
1
2
3
publicevent PropertyChangedEventHandler PropertyChanged;publicvoid OnPropertyChanged(string prop)=>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
по мне так куда быстрее будет работать, чем реализация с рефлексией..(но это не точно)
я только не пойму, почему не использовать старую простую реализацию inpc и вручную писать изменившиеся свойства
Там в одной из веток кода есть эта реализация строка 16 класса OnPropertyChangedClass.
Но кроме того можно вызвать сразу для всех свойств (через рефлексию) или для списка свойств задав их имена или последовательностью, или через разделители.
Необходимость таких способов вызова появилась из практики. Код они не усложняют (пару десятков строк - для базового класса) на скорость обычного вызова OnPropertyChanged() не влияют.
Добавлено через 4 минуты
Сообщение от SatanaXIII
будь добр, выложи пожалуйста проект целиком. Очень полезный и наглядный пример получился.
Сообщение от Рядовой
требуем закрепить его в шапке ветки. Ну или полноценный гайд по mvvm.
Я его "на коленках" делал в "общей свалке" решений. Вытащу в отдельный проект - выложу.