Entwickler-Ecke

WinForms - Custom Textbox wird im Designer nicht angezeigt


Glowhollow - Mo 29.04.19 16:11
Titel: Custom Textbox wird im Designer nicht angezeigt
Grüße

Ich hoffe ich habe diesmal alles richtig gemacht, was tags und Highlighting anbetrifft, sonst köpft Th69 mich wieder ;)

Nein, hat er nicht, aber kann ja demnächst passieren.

Ok, ich habe eine ungewöhnliche Frage.

Da ich ein Autocomplete für eine Textbox brauche, und dies sozusagen selber erweitern wollte, habe ich denke ich soweit alles richtig gemacht, sie wird aber im Designer nicht angezeigt.

Ich extende die Textbox mit meiner eigenen Klasse


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
 public class AutoCompleteTextBox : TextBox
    {
        private string[] database;
        private bool changingText = false;
       
        protected override void OnTextChanged (EventArgs e)
        {
            if (!changingText && database != null)
            {
                string typed = this.Text.Substring(0this.SelectionStart);
                string candidate = null;
                for (int i = 0; i < database.Length; i++)
                    if (database[i].Substring(0this.SelectionStart) == typed)
                    {
                        candidate = database[i].Substring(this.SelectionStart, database[i].Length);
                        break;
                    }
                if (candidate != null)
                {
                    changingText = true;
                    this.Text = typed + candidate;
                    this.SelectionStart = typed.Length;
                    this.SelectionLength = candidate.Length;
                }

            }
            else if (changingText)
                changingText = false;
            base.OnTextChanged(e);
        }
    }


Ja hab ich bei Stackoverflow gefunden. Find ich soweit aber ganz gut.

Ich versuche jetzt über den Designer die Form zu adden. Jedoch bekomme ich eine Fehlermeldung, das die Textbox fehlerhaft ist und daher nicht geadded werden kann. Ich muß zugeben, ich hab noch nie eigene Elemente erweitert. Gibts da irgendwo nen guide dazu ? Oder hab ich da was elementares übersehen ?


Moderiert von user profile iconTh69: Topic aus C# - Die Sprache verschoben am Di 30.04.2019 um 08:22


papa69 - Mo 29.04.19 17:04

Ich hoffe, du nutzt WPF

Hatte ein ~ähnliches Problem~ mit Canvas

vlt hilft es: unterhalb deines grid?, Panel? Dockpanel? what ever

XML-Daten
1:
2:
3:
<local:AutoCompleteTextBox
  x:Name="AutoCompleteTextBox"
  ...weitere Eigenschaften... />


Delete - Mo 29.04.19 17:36

- Nachträglich durch die Entwickler-Ecke gelöscht -


Glowhollow - Di 30.04.19 09:38

@Frühlingsrolle, database befüllst du über getter und setter.

ok, funktioniert nun.

Mußte den Code etwas anpassen, bin aber noch nicht zufrieden damit.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
 public class AutoCompleteTextBox : TextBox
    {
        private string[] database;
        private bool changingText = false;
        public string[] Database { get => database; set => database = value; }

        protected override void OnTextChanged (EventArgs e)
        {
            if (!changingText && database != null)
            {
                string typed = this.Text.Substring(0this.SelectionStart);
                string candidate = null;
                for (int i = 0; i < database.Length; i++)
                    if (database[i].Substring(0,  ((this.SelectionStart >= database[i].Length))? database[i].Length : this.SelectionStart) == typed)
                    {
                        candidate = database[i].Substring(this.SelectionStart, (database[i].Length)-this.SelectionStart);
                        break;
                    }
                if (candidate != null)
                {
                    changingText = true;
                    this.Text = (typed + candidate).ToUpper();
                    this.SelectionStart = typed.Length;
                    this.SelectionLength = candidate.Length;
                }

            }
            else if (changingText)
                changingText = false;
            base.OnTextChanged(e);
        }
    }


Ich lass das mal hier stehen, falls einer das übernehmen möchte. Jedoch fühlt sich das ganze noch unintuitiv an. Wenn man z.bsp. in der Textbox ein paar Sachen löscht, bleibt der jedoch noch bei der Länge-1 stehen, die man zuletzt eingegeben hat. Erst wenn man das ganze feld markiert und löscht kann man wieder ein anderes Suchmuster eingeben.Bin damit noch unzufrieden.

Müßte jetzt die Cursortasten bzw. die Deletetaste abfragen um, den SelectionStart zu modifizieren. Mal sehen ob ich das heute hinbekomme.


Glowhollow - Di 30.04.19 15:10

So, um das gewünschte Verhalten an den Tag zu bringen, mußte ich etwas modifizieren.

Hier das Ergebnis


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
public class AutoCompleteTextBox : TextBox
{
 private string[] database;
 private bool changingText = false;
 private bool checkdelete = false;

 public string[] Database { get => database; set => database = value; }
 public bool ChangingText { get => changingText; set => changingText = value; }
 public bool Checkdelete { get => checkdelete; set => checkdelete = value; }

 protected override void OnTextChanged (EventArgs e)
 {
  if (!checkdelete)
    {
     if (!changingText && database != null)
      {
       string typed = this.Text.Substring(0this.SelectionStart);
       string candidate = null;
       for (int i = 0; i < database.Length; i++)
       if (database[i].Substring(0, ((this.SelectionStart >= database[i].Length)) ? database[i].Length : this.SelectionStart) == typed)
       {
       candidate = database[i].Substring(this.SelectionStart, (database[i].Length) - this.SelectionStart);
       break;
       }
       if (candidate != null)
       {
       changingText = true;
       this.Text = (typed + candidate).ToUpper();

       this.SelectionStart = typed.Length;
       this.SelectionLength = candidate.Length;
       }
       else if (changingText)
       {
       changingText = false;
       checkdelete = false;
       base.OnTextChanged(e);
       }
      } else if (checkdelete)
      {
      checkdelete = false;
      }
     }
    }


Und auf der Textbox liegt noch ein Listener, der die Rücktaste abfrägt und somit das gewünschte Verhalten nachbildet.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
public void TextBoxKeyListener(object sender, KeyEventArgs e)
{
 if (e.KeyCode == Keys.Back)
 {
 var substr = this.tbpishtcsuche2.Text.Substring(0, (this.tbpishtcsuche2.SelectionStart <= this.tbpishtcsuche2.Text.Length) ? this.tbpishtcsuche2.Text.Length - ((this.tbpishtcsuche2.SelectedText.Length == 0)? this.tbpishtcsuche2.SelectedText.Length : this.tbpishtcsuche2.SelectedText.Length-1) : this.tbpishtcsuche2.Text.Length);
 this.tbpishtcsuche2.ChangingText = true;
 this.tbpishtcsuche2.Checkdelete = true;
 this.tbpishtcsuche2.Text = substr;
 this.tbpishtcsuche2.SelectionStart = this.tbpishtcsuche2.Text.Length;
 }
}