Каким будет лучший способ разработать текстовое поле, которое запоминает последние х количество записей, которые были помещены в него. Это автономное приложение, написанное на C#.Google Предлагает текстовое поле (автозаполнение)
ответ
Я забыл о том, что вы хотели бы сохранить, что так не было на сессии только вещь: P Но да, вы совершенно правы.
Это легко сделать, тем более, что это просто базовые строки, просто напишите содержимое AutoCompleteCustomSource из текстового поля в текстовый файл на отдельных строках.
У меня было несколько минут, поэтому я написал полный пример кода ... Я бы хотел, прежде чем пытаться показать код, но не успел. Во всяком случае, вот и все (минус код дизайнера).
namespace AutoComplete
{
public partial class Main : Form
{
//so you don't have to address "txtMain.AutoCompleteCustomSource" every time
AutoCompleteStringCollection acsc;
public Main()
{
InitializeComponent();
//Set to use a Custom source
txtMain.AutoCompleteSource = AutoCompleteSource.CustomSource;
//Set to show drop down *and* append current suggestion to end
txtMain.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
//Init string collection.
acsc = new AutoCompleteStringCollection();
//Set txtMain's AutoComplete Source to acsc
txtMain.AutoCompleteCustomSource = acsc;
}
private void txtMain_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//Only keep 10 AutoComplete strings
if (acsc.Count < 10)
{
//Add to collection
acsc.Add(txtMain.Text);
}
else
{
//remove oldest
acsc.RemoveAt(0);
//Add to collection
acsc.Add(txtMain.Text);
}
}
}
private void Main_FormClosed(object sender, FormClosedEventArgs e)
{
//open stream to AutoComplete save file
StreamWriter sw = new StreamWriter("AutoComplete.acs");
//Write AutoCompleteStringCollection to stream
foreach (string s in acsc)
sw.WriteLine(s);
//Flush to file
sw.Flush();
//Clean up
sw.Close();
sw.Dispose();
}
private void Main_Load(object sender, EventArgs e)
{
//open stream to AutoComplete save file
StreamReader sr = new StreamReader("AutoComplete.acs");
//initial read
string line = sr.ReadLine();
//loop until end
while (line != null)
{
//add to AutoCompleteStringCollection
acsc.Add(line);
//read again
line = sr.ReadLine();
}
//Clean up
sr.Close();
sr.Dispose();
}
}
}
Этот код будет работать точно так, как есть, вам просто нужно создать графический интерфейс с TextBox именем txtMain и подключить KeyDown, закрытые и загружаемыми в TextBox и главной форме.
Также обратите внимание, что для этого примера и для его простого я просто решил определить, что клавиша Enter нажата как мой триггер, чтобы сохранить строку в коллекции. Вероятно, будет больше/разных событий, которые будут лучше, в зависимости от ваших потребностей.
Кроме того, модель, используемая для заполнения коллекции, не очень «умна». Он просто удаляет самую старую строку, когда коллекция достигает предела 10. Это, вероятно, не идеально, но работает для примера.Вероятно, вам нужна какая-то рейтинговая система (особенно, если вы действительно хотите, чтобы это был Google-ish)
Заключительное примечание. Предложения действительно будут отображаться в том порядке, в котором они находятся в коллекции. Если по какой-то причине вы хотите, чтобы они отображались по-другому, просто отсортируйте список, как вам нравится.
Надеюсь, что это поможет!
Это на самом деле довольно просто, особенно с точки зрения отображения части автозаполнения. Что касается запоминания последнего количества записей, вам просто нужно будет принять решение о конкретном событии (или событиях), которое вы считаете завершаемой записью, и записать эту запись в список ... AutoCompleteStringCollection будет точный.
Класс TextBox имеет 3 следующие свойства, которые вам понадобятся:
- AutoCompleteCustomSource
- AutoCompleteMode
- AutoCompleteSource
Set AutoCompleteMode к SuggestAppend и AutoCompleteSource к CustomSource.
Затем во время выполнения каждый раз, когда создается новая запись, используйте метод Add() для AutoCompleteStringCollection, чтобы добавить эту запись в список (и удалите все старые, если хотите). Вы можете выполнить эту операцию непосредственно в свойстве AutoCompleteCustomSource TextBox, если вы уже инициализировали его.
Теперь, каждый раз, когда вы вводите в TextBox он предложит предыдущие записи :)
этой статью для более полного примера: http://www.c-sharpcorner.com/UploadFile/mahesh/AutoCompletion02012006113508AM/AutoCompletion.aspx
автозаполнения также имеет некоторые встроенные функции, как FileSystem и URL-адрес (хотя это только материал, который был набран в IE ...)
Я сохраняю список завершений в реестре.
Код, который я использую, приведен ниже. Он может использоваться повторно в три этапа:
- заменить пространство имен и имя класса в этом коде тем, что вы используете.
- Вызвать FillFormFromRegistry() в форме формы. Загрузите событие и вызовите SaveFormToRegistry на Закрытие события.
- скомпилируйте это в свой проект.
Вам необходимо украсить сборку двумя атрибутами: [assembly: AssemblyProduct("...")]
и [assembly: AssemblyCompany("...")]
. (Эти атрибуты обычно устанавливаются автоматически в проектах, созданных в Visual Studio, поэтому я не считаю это как шаг.)
Управление состоянием таким образом полностью автоматизировано и прозрачно для пользователя.
Вы можете использовать один и тот же шаблон для хранения любого состояния вашего приложения WPF или WinForms. Как состояние текстовых полей, флажки, выпадающие списки. Также вы можете store/restore the size of the window - очень удобно - в следующий раз, когда пользователь запускает приложение, он открывается в том же месте и с тем же размером, что и при закрытии. Вы можете store the number of times an app has been run. Много возможностей.
namespace Ionic.ExampleCode
{
public partial class NameOfYourForm
{
private void SaveFormToRegistry()
{
if (AppCuKey != null)
{
// the completion list
var converted = _completions.ToList().ConvertAll(x => x.XmlEscapeIexcl());
string completionString = String.Join("¡", converted.ToArray());
AppCuKey.SetValue(_rvn_Completions, completionString);
}
}
private void FillFormFromRegistry()
{
if (!stateLoaded)
{
if (AppCuKey != null)
{
// get the MRU list of .... whatever
_completions = new System.Windows.Forms.AutoCompleteStringCollection();
string c = (string)AppCuKey.GetValue(_rvn_Completions, "");
if (!String.IsNullOrEmpty(c))
{
string[] items = c.Split('¡');
if (items != null && items.Length > 0)
{
//_completions.AddRange(items);
foreach (string item in items)
_completions.Add(item.XmlUnescapeIexcl());
}
}
// Can also store/retrieve items in the registry for
// - textbox contents
// - checkbox state
// - splitter state
// - and so on
//
stateLoaded = true;
}
}
}
private Microsoft.Win32.RegistryKey AppCuKey
{
get
{
if (_appCuKey == null)
{
_appCuKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(AppRegistryPath, true);
if (_appCuKey == null)
_appCuKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(AppRegistryPath);
}
return _appCuKey;
}
set { _appCuKey = null; }
}
private string _appRegistryPath;
private string AppRegistryPath
{
get
{
if (_appRegistryPath == null)
{
// Use a registry path that depends on the assembly attributes,
// that are presumed to be elsewhere. Example:
//
// [assembly: AssemblyCompany("Dino Chiesa")]
// [assembly: AssemblyProduct("XPathVisualizer")]
var a = System.Reflection.Assembly.GetExecutingAssembly();
object[] attr = a.GetCustomAttributes(typeof(System.Reflection.AssemblyProductAttribute), true);
var p = attr[0] as System.Reflection.AssemblyProductAttribute;
attr = a.GetCustomAttributes(typeof(System.Reflection.AssemblyCompanyAttribute), true);
var c = attr[0] as System.Reflection.AssemblyCompanyAttribute;
_appRegistryPath = String.Format("Software\\{0}\\{1}",
p.Product, c.Company);
}
return _appRegistryPath;
}
}
private Microsoft.Win32.RegistryKey _appCuKey;
private string _rvn_Completions = "Completions";
private readonly int _MaxMruListSize = 14;
private System.Windows.Forms.AutoCompleteStringCollection _completions;
private bool stateLoaded;
}
public static class Extensions
{
public static string XmlEscapeIexcl(this String s)
{
while (s.Contains("¡"))
{
s = s.Replace("¡", "¡");
}
return s;
}
public static string XmlUnescapeIexcl(this String s)
{
while (s.Contains("¡"))
{
s = s.Replace("¡", "¡");
}
return s;
}
public static List<String> ToList(this System.Windows.Forms.AutoCompleteStringCollection coll)
{
var list = new List<String>();
foreach (string item in coll)
{
list.Add(item);
}
return list;
}
}
}
Некоторые люди shy away from using the Registry for storing state, но я считаю, что это очень легко и удобно. Если вам нравится, вы можете легко создать установщик, который удаляет все разделы реестра при удалении.