문제

입력된 마지막 x개 항목을 기억하는 텍스트 상자를 개발하는 가장 좋은 방법은 무엇입니까?C#으로 작성된 독립형 앱입니다.

도움이 되었습니까?

해결책

@에단

나는 당신이 그것을 저장하고 싶다는 사실을 잊어버렸기 때문에 그것은 세션당 유일한 것이 아니었습니다 :P 그러나 그렇습니다, 당신은 완전히 옳습니다.

이는 특히 기본 문자열이기 때문에 쉽게 수행할 수 있습니다. AutoCompleteCustomSource의 내용을 TextBox의 텍스트 파일에 별도의 줄에 작성하면 됩니다.

몇 분의 시간이 있어서 완전한 코드 예제를 작성했습니다... 항상 코드를 보여주려고 노력했기 때문에 이전에도 그랬을 텐데 시간이 없었습니다.어쨌든, 여기에 모든 것이 있습니다(디자이너 코드 제외).

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

이 코드는 그대로 작동합니다. txtMain이라는 TextBox를 사용하여 GUI를 만들고 KeyDown, Closed 및 Load 이벤트를 TextBox 및 Main 양식에 연결하기만 하면 됩니다.

또한 이 예에서는 간단하게 만들기 위해 문자열을 컬렉션에 저장하기 위한 트리거로 Enter 키를 누르는 것을 감지하도록 선택했습니다.귀하의 필요에 따라 더 좋은 이벤트가 더 많거나 다를 수 있습니다.

또한 컬렉션을 채우는 데 사용되는 모델은 그다지 "스마트"가 아닙니다. 컬렉션이 10이라는 한계에 도달하면 가장 오래된 문자열을 단순히 삭제합니다.이는 이상적이지는 않지만 예제에서는 작동합니다.아마도 일종의 평가 시스템을 원할 것입니다(특히 Google과 같은 시스템을 정말로 원하는 경우).

마지막으로 제안 사항은 실제로 컬렉션에 있는 순서대로 표시됩니다.어떤 이유로든 다르게 표시되도록 하려면 원하는 대로 목록을 정렬하면 됩니다.

도움이 되었기를 바랍니다!

다른 팁

특히 "자동 완성" 부분을 표시한다는 측면에서 이는 실제로 상당히 쉽습니다.마지막 x개 항목을 기억한다는 측면에서 항목이 완료된 것으로 간주하는 특정 이벤트(또는 이벤트)를 결정하고 해당 항목을 목록에 기록하면 됩니다.정확하게 말하면 AutoCompleteStringCollection입니다.

TextBox 클래스에는 다음과 같은 3가지 필요한 속성이 있습니다.

  • 자동 완성사용자 정의 소스
  • 자동 완성 모드
  • 자동 완성 소스

AutoCompleteMode를 SuggestAppend로 설정하고 AutoCompleteSource를 CustomSource로 설정합니다.

그런 다음 런타임에 새 항목이 만들어질 때마다 AutoCompleteStringCollection의 Add() 메서드를 사용하여 해당 항목을 목록에 추가합니다(원하는 경우 이전 항목을 제거합니다).이미 초기화했다면 TextBox의 AutoCompleteCustomSource 속성에서 직접 이 작업을 수행할 수 있습니다.

이제 TextBox에 입력할 때마다 이전 항목이 제안됩니다. :)

더 완전한 예를 보려면 다음 문서를 참조하세요. http://www.c-sharpcorner.com/UploadFile/mahesh/AutoCompletion02012006113508AM/AutoCompletion.aspx

AutoComplete에는 FileSystem 및 URL과 같은 기능이 내장되어 있습니다(IE에 입력된 작업만 수행하지만...).

완성 목록을 레지스트리에 저장합니다.

내가 사용하는 코드는 다음과 같습니다.다음 세 단계를 거쳐 재사용이 가능합니다.

  1. 이 코드의 네임스페이스와 클래스 이름을 사용하는 이름으로 바꾸세요.
  2. 양식에서 FillFormFromRegistry()를 호출합니다. 이벤트를 실행하고 SaveFormToRegistry를 호출합니다. 폐쇄 이벤트.
  3. 이것을 프로젝트에 컴파일하십시오.

다음 두 가지 속성으로 어셈블리를 장식해야 합니다. [assembly: AssemblyProduct("...")] 그리고 [assembly: AssemblyCompany("...")] .(이러한 특성은 일반적으로 Visual Studio 내에서 생성된 프로젝트에서 자동으로 설정되므로 이를 한 단계로 계산하지 않습니다.)

이러한 방식으로 상태를 관리하는 것은 완전히 자동이며 사용자에게 투명합니다.

동일한 패턴을 사용하여 WPF 또는 WinForms 앱에 대한 모든 종류의 상태를 저장할 수 있습니다.텍스트 상자, 확인란, 드롭다운의 상태와 같습니다.또한 당신은 할 수 있습니다 창 크기 저장/복원 - 정말 편리합니다. 다음에 사용자가 앱을 실행하면 앱을 닫았을 때와 동일한 위치, 동일한 크기로 열립니다.당신은 할 수 있습니다 앱이 실행된 횟수 저장.많은 가능성.

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

어떤 사람들은 상태를 저장하기 위해 레지스트리를 사용하는 것을 꺼려하세요, 하지만 정말 쉽고 편리하다고 생각합니다.원하는 경우 제거 시 모든 레지스트리 키를 제거하는 설치 프로그램을 매우 쉽게 구축할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top