TextBox AutoComplete не работает должным образом - PullRequest
3 голосов
/ 28 февраля 2012

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

Этот код, который я написал в событии textchange.

arr = LoadName(empid_txt.Text.Trim());  //arr is string array                          
namesCollection.AddRange(arr);
this.empid_txt.AutoCompleteMode = AutoCompleteMode.Suggest;
this.empid_txt.AutoCompleteSource = AutoCompleteSource.CustomSource;
this.empid_txt.AutoCompleteCustomSource = namesCollection;

В LoadEvent я инициализировал AutoCompleteNameCollection с пустым массивом.

namesCollection.AddRange(arr);// here arr is empty
empid_txt.AutoCompleteMode = AutoCompleteMode.Suggest;
empid_txt.AutoCompleteSource = AutoCompleteSource.CustomSource;
empid_txt.AutoCompleteCustomSource = namesCollection;

Но это не работает до ввода второго символа.Однако, если вместо массива я инициализирую AutoCompleteNameCollection пустой строкой, например: namesCollection.Add ("");он работает для односимвольного ввода, но иногда дает AccessViolationException: Попытка чтения или записи в защищенную память.Так есть ли способ, которым я могу решить эту проблему?

Ответы [ 5 ]

2 голосов
/ 12 марта 2012

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

Чтобы предотвратить это, вы можете установить блокировку вокруг вашего кода.

lock(this)
{
arr = LoadName(empid_txt.Text.Trim());  //arr is string array                          
namesCollection.AddRange(arr);
this.empid_txt.AutoCompleteMode = AutoCompleteMode.Suggest;
this.empid_txt.AutoCompleteSource = AutoCompleteSource.CustomSource;
this.empid_txt.AutoCompleteCustomSource = namesCollection;
}

Это остановило нарушения доступа.

1 голос
/ 13 марта 2012

При загрузке вы можете заполнить TextBox подмножеством ваших данных (которые могут быть даже кэшированы для будущего / общего использования).Если у вас есть «самый распространенный» счетчик, вы можете использовать его.В качестве предельного условия вы можете даже добавить элемент dummy (если то, что вы получаете с пустой строкой, является нарушением прав доступа).Затем при событии TextChange прочитайте необходимые данные из базы данных.

У меня только один вопрос: вы не хотите заполнять источник, пока пользователь не начнет печатать?Если существует проблема сетевого трафика, вы перемещаете много данных.Если вы перемещаете много данных, тогда вашим пользователям придется ждать, когда они начнут что-то печатать.Это приемлемо?С другой стороны, если они не ждут слишком много, возможно, поток данных не так велик, и вы можете поместить эту логику в BackgroundWorker в конструкторе вашей формы (или недалеко от того времени).

1 голос
/ 11 марта 2012

AutoComplete предполагает, что после нажатия второго символа нормально, потому что, во-первых, вы инициализировали arr (который является вашим пользовательским источником данных) в пустой массив.Вы заполнили событие arr в TextChanged, и поэтому AutoComplete работает на втором символе, потому что ваш источник данных фильтруется на основе вашего первого символа (, что определенно не нужно ),

Вот предложение:

  • В событии FormLoad вашей заявки заполните arr всеми возможными предложениями ( Я думаю, что источникпредложение из базы данных верно? ).Это позволит текстовому полю предложить ваш первый символ.

  • Когда вы ввели первый символ, при событии TextChanged перезагрузите ваш источник данных arr на основе введенного преобладающего символа..

Надеюсь, это поможет.

0 голосов
/ 10 марта 2014

При загрузке формы вызовите метод автозаполнения Textbox.

 public void autocompleteData()
    {
            //SuggestStrings will have the logic to return array of strings either from cache/db
            var CurrentuserId = CloudKaseWSClient.GetUserDetail(tokenUsr, tokenPasswd, Username);
            List<string> l = new List<string>();
            var SearchResults = ("Select Database Query").ToList();
            foreach (var i in SearchResults)
            {
                l.Add(i.name);
            }
            string[] arr = l.ToArray();
            AutoCompleteStringCollection collection = new AutoCompleteStringCollection();
            collection.AddRange(arr);

        txtSearchUser.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
        txtSearchUser.AutoCompleteSource = AutoCompleteSource.CustomSource;
        txtSearchUser.AutoCompleteCustomSource = collection;
    }

ИЛИ Вы хотите установить статические данные для текстового поля автозаполнения, чем необходимо установить в представлении «Дизайн» для свойства «Текстовое поле» объекта AutocompleteMode, чтобы задать параметр SuggestAppend, AutocompleteSource для установки CustomSource и добавить статическое значение в AutoCompleteCustomSource.

Я надеюсь, что это решение поможет вам .. Удачного кодирования .:)

0 голосов
/ 28 февраля 2012

Если при инициализации текстового поля 'arr' пусто, сравнивать не с чем. Вы должны инициализировать AutoCompleteCustomSource в допустимый массив, прежде чем начать печатать. Вы инициализируете событие textchange, когда пользователь уже набрал символ.

Вам нужно заполнить namesCollection до того, как код будет изменен - ​​в Initialize.

...