سؤال

ما هي أفضل طريقة لتطوير مربع نص يتذكر آخر عدد × من الإدخالات التي تم وضعها فيه.هذا تطبيق مستقل مكتوب باستخدام 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();
        }
    }
}

سيعمل هذا الرمز تمامًا كما هو، كل ما عليك فعله هو إنشاء واجهة المستخدم الرسومية باستخدام TextBox المسمى txtMain وربط الأحداث KeyDown وClosed وLoad بالنموذج TextBox والنموذج الرئيسي.

لاحظ أيضًا أنه في هذا المثال، ولجعل الأمر بسيطًا، اخترت فقط اكتشاف مفتاح Enter الذي يتم الضغط عليه كمشغل لحفظ السلسلة في المجموعة.ربما يكون هناك المزيد/الأحداث المختلفة التي قد تكون أفضل، اعتمادًا على احتياجاتك.

أيضا ، فإن النموذج المستخدم لملء المجموعة ليس "ذكيا". إنه ببساطة يحذف أقدم سلسلة عندما تصل المجموعة إلى الحد 10.من المحتمل ألا يكون هذا مثاليًا، ولكنه يعمل كمثال.ربما تريد نوعًا ما من نظام التصنيف (خاصة إذا كنت تريده حقًا أن يكون Google-ish)

ملاحظة أخيرة، ستظهر الاقتراحات فعليًا بالترتيب الذي كانت عليه في المجموعة.إذا كنت تريد ظهورهم بشكل مختلف لسبب ما، فما عليك سوى فرز القائمة كيفما تشاء.

امل ان يساعد!

نصائح أخرى

وهذا في الواقع سهل إلى حد ما، خاصة فيما يتعلق بإظهار جزء "الإكمال التلقائي" منه.فيما يتعلق بتذكر آخر عدد x من الإدخالات، سيتعين عليك فقط اتخاذ قرار بشأن حدث معين (أو أحداث) تعتبرها بمثابة إدخال قيد الاكتمال وكتابة هذا الإدخال في القائمة...AutoCompleteStringCollection على وجه الدقة.

تحتوي فئة TextBox على الخصائص الثلاثة التالية التي ستحتاج إليها:

  • الإكمال التلقائي للمصدر المخصص
  • وضع الإكمال التلقائي
  • مصدر الإكمال التلقائي

قم بتعيين وضع الإكمال التلقائي على SuggestAppend وAutoCompleteSource على CustomSource.

ثم في وقت التشغيل، في كل مرة يتم فيها إجراء إدخال جديد، استخدم طريقة Add() الخاصة بـ AutoCompleteStringCollection لإضافة هذا الإدخال إلى القائمة (وحذف أي إدخالات قديمة إذا أردت ذلك).يمكنك بالفعل إجراء هذه العملية مباشرة على خاصية AutoCompleteCustomSource الخاصة بـ TextBox طالما قمت بتهيئتها بالفعل.

الآن، في كل مرة تكتب فيها في TextBox، سيقترح عليك إدخالات سابقة :)

راجع هذه المقالة للحصول على مثال أكثر اكتمالا: http://www.c-sharpcorner.com/UploadFile/mahesh/AutoCompletion02012006113508AM/AutoCompletion.aspx

يحتوي الإكمال التلقائي أيضًا على بعض الميزات المضمنة مثل 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