5

最後の x 個のエントリが入力されたことを記憶するテキスト ボックスを作成する最良の方法は何でしょうか。これは、C# で記述されたスタンドアロン アプリです。

4

3 に答える 3

6

これは、特に「オートコンプリート」部分を表示するという点で、実際にはかなり簡単です。最後の x 個のエントリを記憶するという点では、エントリが完了したと見なす特定のイベント (または複数のイベント) を決定し、そのエントリをリストに書き出す必要があります... AutoCompleteStringCollection を正確。

TextBox クラスには、必要な次の 3 つのプロパティがあります。

  • AutoCompleteCustomSource
  • オートコンプリート モード
  • オートコンプリートソース

AutoCompleteMode を SuggestAppend に、AutoCompleteSource を CustomSource に設定します。

次に、実行時に、新しいエントリが作成されるたびに、AutoCompleteStringCollection の Add() メソッドを使用して、そのエントリをリストに追加します (必要に応じて古いエントリを削除します)。この操作は、既に初期化されている限り、TextBox の AutoCompleteCustomSource プロパティで直接実行できます。

これで、TextBox に入力するたびに、以前のエントリが提案されます :)

より完全な例については、この記事を参照してください: http://www.c-sharpcorner.com/UploadFile/mahesh/AutoCompletion02012006113508AM/AutoCompletion.aspx

AutoComplete には、FileSystem や URL などの組み込み機能もあります (ただし、IE に入力されたものしか実行しません...)。

于 2008-09-04T01:29:21.983 に答える
3

@イーサン

私はあなたがそれを保存したいと思うという事実を忘れたので、それはセッションごとだけのものではありませんでした: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の制限に達すると、最も古い文字列を削除するだけです。これは理想的ではない可能性がありますが、例では機能します。あなたはおそらくある種の評価システムが欲しいでしょう(特にあなたが本当にそれをグーグルっぽくしたいのなら)

最後に、提案は実際にはコレクションにある順序で表示されます。何らかの理由で表示を変えたい場合は、リストを好きなように並べ替えてください。

お役に立てば幸いです。

于 2008-09-05T01:17:21.957 に答える
1

完了リストをレジストリに保存します。

私が使用するコードは以下のとおりです。次の3つのステップで再利用できます。

  1. このコードの名前空間とクラス名を、使用するものに置き換えます。
  2. フォームのLoadイベントでFillFormFromRegistry()を呼び出し、ClosingイベントでSaveFormToRegistryを呼び出します。
  3. これをプロジェクトにコンパイルします。

アセンブリを2つの属性で装飾する必要があります:[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;
        }
    }
}

状態を保存するためにレジストリを使用することを躊躇する人もいますが、それは本当に簡単で便利だと思います。必要に応じて、アンインストール時にすべてのレジストリキーを削除するインストーラーを非常に簡単に構築できます。

于 2009-09-17T22:31:14.243 に答える