Pregunta

¿Cuál sería la mejor manera de desarrollar un cuadro de texto que recuerda la última de x el número de entradas que se pusieron en ella.Esta es una aplicación independiente escrito en C#.

¿Fue útil?

Solución

@Ethan

Se me olvidó el hecho de que desea guardar que no era por sesión única cosa :P Pero sí, está todo correcto.

Esto es fácil de hacer, especialmente ya que es solo lo básico de las cadenas, sólo tiene que escribir el contenido de AutoCompleteCustomSource desde el cuadro de texto a un archivo de texto, en líneas separadas.

Yo tenía un par de minutos, así que escribí un ejemplo de código completo...me hubiera antes, como siempre trato de mostrar el código, pero no tenía tiempo.De todos modos, aquí está toda la cosa (menos el código de diseñador).

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();
        }
    }
}

Este código funcionará exactamente como es, usted sólo tiene que crear la interfaz gráfica de usuario con un cuadro de texto denominado txtMain y conectar el KeyDown, Cerrado y eventos de Carga en el cuadro de texto y el formulario Principal.

También tenga en cuenta que, para este ejemplo y hacer que sea sencillo, simplemente me eligió para detectar la tecla Enter ser presionado como mi gatillo para guardar la cadena para la colección.Probablemente hay más/los diferentes eventos que sería mejor, dependiendo de sus necesidades.

También, el modelo utilizado para rellenar la colección no es muy "inteligente". Simplemente elimina la más antigua de la cadena cuando la colección se hace con el límite de 10.Es probable que esto no es ideal, pero trabaja para el ejemplo.Probablemente desee algún tipo de sistema de clasificación (especialmente si usted realmente quiere que sea de Google-ish)

Una nota final, las sugerencias realmente aparecerán en el orden que se encuentran en la colección.Si por alguna razón usted desea que se muestren de forma diferente, acaba de ordenar la lista, sin embargo, te gusta.

Espero que ayude!

Otros consejos

Esta es en realidad bastante fácil, especialmente en términos de mostrar el "Autocompletar" parte de ello.En términos de recordar la última de x número de entradas, sólo se va a tener que decidir en un determinado evento (o eventos) que considere la posibilidad de entrada como un ser completado y escribir esa entrada a una lista de...un AutoCompleteStringCollection para ser precisos.

En el cuadro de texto de la clase de los 3 siguientes propiedades que se necesitan:

  • AutoCompleteCustomSource
  • AutoCompleteMode
  • AutoCompleteSource

Conjunto de AutoCompleteMode a SuggestAppend y AutoCompleteSource a CustomSource.

Luego en tiempo de ejecución, cada vez que una nueva entrada, utilice el método Add() de AutoCompleteStringCollection añadir que la entrada a la lista (y el pop fuera de cualquier edad si lo desea).En realidad se puede hacer esta operación directamente en el AutoCompleteCustomSource propiedad de la caja de texto tan largo como usted ya ha inicializado ella.

Ahora, cada vez que escriba en el cuadro de texto se sugieren las entradas anteriores :)

Consulte este artículo para obtener un ejemplo más completo: http://www.c-sharpcorner.com/UploadFile/mahesh/AutoCompletion02012006113508AM/AutoCompletion.aspx

Autocompletar también tiene algunas construido en características como el sistema de archivos y direcciones Url (a pesar de que sólo hace cosas que se ha escrito en IE...)

Me guarde la lista de finalización en el registro.

El código que uso es de abajo.Es reutilizable, en tres pasos:

  1. reemplazar el espacio de nombres y el nombre de la clase en este código, con todo lo que se utilice.
  2. Llame a la FillFormFromRegistry() en el Formulario Carga evento, y llame a SaveFormToRegistry en el Cierre evento.
  3. compilar esta en su proyecto.

Usted necesita para decorar la asamblea con dos atributos: [assembly: AssemblyProduct("...")] y [assembly: AssemblyCompany("...")] .(Estos atributos se colocan automáticamente en los proyectos creados en Visual Studio, así que no cuenta como un paso).

Administrar el estado de esta manera es totalmente automática y transparente para el usuario.

Usted puede utilizar el mismo patrón para almacenar cualquier tipo de estado para su WPF o WinForms aplicación.Como el estado de los cuadros de texto, casillas de verificación, listas desplegables.También puede guardar/restaurar el tamaño de la ventana - muy útil - la próxima vez que el usuario ejecuta la aplicación, se abre en el mismo lugar, y con el mismo tamaño, como cuando se cerró.Usted puede almacenar el número de veces que una aplicación se ha ejecutado.Un montón de posibilidades.

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("¡", "&#161;");
            }
            return s;
        }
        public static string XmlUnescapeIexcl(this String s)
        {
            while (s.Contains("&#161;"))
            {
                s = s.Replace("&#161;", "¡");
            }
            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;
        }
    }
}

Algunas personas evitar usar el Registro para el estado de almacenamiento, pero me parece que es realmente fácil y conveniente.Si te gusta, Usted puede construir fácilmente un instalador que elimina todas las claves de registro en desinstalar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top