Entwickler-Ecke
WinForms - AutoCompleteMenu
Csharp-programmierer - Mi 13.04.16 17:49
Titel: AutoCompleteMenu
Hallo :-)
Ich habe mir die .dll von dem AutoCompletemMenu runtergeladen und implimentiert, damit das Scintilla damit arbeiten kann. Wenn ich versuche, die .dll in den Werkzeugkasten aufzunehmen, sagt VS mir, dass keine Komponente gefunden wurde, die man in den Werkzeugkasten positionieren kann.
Also habe ich mir das Scintilla und das ACM per Code erstellt:
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:
| public partial class Form1 : Form { AutocompleteMenu auto = new AutocompleteMenu(); public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { Scintilla sc = new Scintilla(); sc.Dock = DockStyle.Fill; sc.TextChanged += new EventHandler(Hallo); auto.TargetControlWrapper = new ScintillaWrapper(sc); BuildAutoComleteMenu();
this.Controls.Add(sc); }
private void Hallo(object sender, EventArgs e) { Scintilla sc = sender as Scintilla; if (sc != null) auto.Show(sc, true); }
private void BuildAutoComleteMenu() { string[] snippets = { "<h1></h1>", "<center></center>", "<div id=\"\"></div" }; var items = new List<AutocompleteItem>();
foreach (var item in snippets) items.Add(new SnippetAutocompleteItem(item) { ImageIndex = 1 }); auto.SetAutocompleteItems(items); } } |
Jetzt ist es jedoch so, dass das ACM IMMER da ist, obwohl ich es nicht möchte und das Item in der Mitte kann ich nicht anklicken. Kann man das irgendwie so machen, dass es wie in VS funktioniert?
Moderiert von
Christian S.: Topic aus Sonstiges (.NET) verschoben am Mi 13.04.2016 um 19:03
Christian S. - Mi 13.04.16 19:00
Was ist denn "das" AutoCompleteMenu. Gibt es da nur eins? Müssen wir das jetzt selber suchen, um zu wissen, was Du benutzt?
Offensichtlich wird auto.Show im TextChanged-Ereignis aufgerufen, also wird es wohl wenig überraschend bei jedem Ändern des Textes erscheinen. Wenn Du es anders willst, muss Du es anders programmieren - da Du aber nicht sagst, was Du willst, können wir Dir dabei nicht helfen.
So, und jetzt noch ein offizieller Hinweis von meiner Seite: Ich möchte Dich bitten, Dir mehr Mühe bei der Formulierung Deiner Fragen zu geben. Es ist nicht okay, dass die Leute, die Dir eigentlich helfen wollen, erst einmal recherchieren oder schlicht raten müssen, um Deine Frage oder den Kontext zu verstehen. Du musst Dich bitte mehr in uns, die wir nicht vor Deinem Programm sitzen, hinein versetzen. Ich weiß, das ist nicht so leicht, wie es klingt, aber man kann das auch üben! Wir wissen nur das, was Du hier schreibst. Und zwar auch nur das, was Du in diesem einen Beitrag schreibst, weil keiner erst einmal Deine bisherigen Beiträge nachlesen will. Nimm's mir bitte nicht übel, aber das muss jetzt einfach mal besser werden :mahn:
Csharp-programmierer - Mi 13.04.16 19:12
Entschuldigung, richtiges Beschreiben der Probleme zählt nicht zu meinen Stärken. Trotzdem versuche ich in Zukunft - so gut es geht - das Problem so detalliert wie möglich zu beschreiben.
Das ACM habe ich gedownloadet:
http://www.codeproject.com/Articles/365974/Autocomplete-Menu
Zitat: |
Offensichtlich wird auto.Show im TextChanged-Ereignis aufgerufen, also wird es wohl wenig überraschend bei jedem Ändern des Textes erscheinen. Wenn Du es anders willst, muss Du es anders programmieren - da Du aber nicht sagst, was Du willst, können wir Dir dabei nicht helfen. |
Ich habe ohne das TextChanged Ereignis schon versucht, die AutoPopup - Propertie auf true zu stellen, jedoch wird das ACM dann immer noch nicht angezeigt :(
Christian S. - Mi 13.04.16 19:31
Du kannst Dir mal den Designer-Code in dem Beispielcode ansehen. Also z.B. den Konstruktor in der Datei SimpleSample.Designer.cs. Da wird z.B. einmalig beim Erstellen die Methode this.autocompleteMenu1.SetAutocompleteMenu(this.richTextBox1, this.autocompleteMenu1); aufgerufen, das wirst Du wohl mit Deinem Scintilla auch machen müssen. TargetControlWrapper wird dagegen auf null gesetzt.
Im übrigen: Wenn ich bei mir das AutoCompleteMenu-Projekt (also die Sourcen, nicht die fertige DLL) in meine Projektmappe einbinde, erscheint es nach dem ersten Build automatisch in meiner Toolbox. Klappt ja vielleicht auch bei Dir!
Csharp-programmierer - Mi 13.04.16 19:56
Ich verstehe es nicht. In VS 2010 kann ich die DLLs ganz einfach implimentieren und sie werden in der Toolbox angezeigt. In VS 2013 stehen zwar alle Verweise da, aber im Werkzeugkasten ist nichts.
Gibt es auch eine Möglischkeit, diese Elemente auch ohne Toolbox zu erstellen?
Christian S. - Mi 13.04.16 19:59
Hast Du meinen ersten Absatz gelesen? ;-)
Csharp-programmierer - Mi 13.04.16 20:07
Ja habe ich. Das habe ich aber nicht verstanden:(
Christian S. - Mi 13.04.16 20:13
Aha
Ich bin jetzt mal genauso informativ ...
Ralf Jansen - Mi 13.04.16 20:15
Ich spring kurz mal in die Rate runde mit ein.
Du hast ein Control mit Beispielcode heruntergeladen. Und wir möchten einfach das du dir den Beispielcode ansiehst. Zum Beispiel die von Christian besagte "SimpleSample.Designer.cs".
Wenn du ein Control aus der Toolbox auf eine Form ziehst geschieht keine versteckte Magie. Es wird Code erzeugt, genauso Code wie du ihn schreiben möchtest. Der Code steckt in der IRGENDWAS.Designer.cs Datei die zu jeder Form erstellt wird und du im Solutionexplorer(oder falls du dich dummerweise mit einem deutschen Visual Studio rumschlägst der Projektmappen-Explorer) einfach wie jede andere Datei deines Projects öffnen kannst. Wenn du also wissen möchtest welchen Code du möglicherweise schreiben möchtest hilft es sich den anzuschauen den der Designer erzeugt hat du müsstest halt ähnliches/das gleiche tun.
Csharp-programmierer - Mi 13.04.16 20:36
Der Designer Code in meinem Projekt:
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: 45: 46:
| namespace WindowsFormsApplication2 { partial class Form1 { private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); }
#region Vom Windows Form-Designer generierter Code
private void InitializeComponent() { this.SuspendLayout(); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(766, 355); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false);
}
#endregion } } |
Csharp-programmierer - Mi 13.04.16 21:06
Jetzt funktioniert es. Was ich jetzt aber nicht verstehe, wenn ich diesen Code habe, funktioniert alls:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| private void Form1_Load(object sender, EventArgs e) { Scintilla scin = new Scintilla(); scin.Dock = DockStyle.Fill;
AutocompleteMenu autocompleteMenu1 = new AutocompleteMenu(); autocompleteMenu1.SetAutocompleteMenu(scin, autocompleteMenu1); autocompleteMenu1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); autocompleteMenu1.ImageList = null; autocompleteMenu1.Items = new string[] { "abc", "abcd", "abcde", "abcdef"}; autocompleteMenu1.LeftPadding = 0; autocompleteMenu1.TargetControlWrapper = null; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; autocompleteMenu1.TargetControlWrapper = new ScintillaWrapper(scin); this.Controls.Add(scin); } |
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: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| partial class Form1 { private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); }
#region Vom Windows Form-Designer generierter Code
private void InitializeComponent() { this.SuspendLayout(); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(766, 355); ScintillaNET.Scintilla scintilla1 = new ScintillaNET.Scintilla(); scintilla1.Name = "scintilla1"; AutocompleteMenuNS.AutocompleteMenu autocompleteMenu1 = new AutocompleteMenuNS.AutocompleteMenu(); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false);
autocompleteMenu1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); autocompleteMenu1.ImageList = null; autocompleteMenu1.Items = new string[] { "abc", "abcd", "abcde", "abcdef"}; autocompleteMenu1.LeftPadding = 0;
autocompleteMenu1.TargetControlWrapper = new ScintillaWrapper(scintilla1); }
#endregion } |
Wenn ich nun aber die Strings austausche, erscheint das Menü nicht mehr :(
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:
| public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { Scintilla scin = new Scintilla(); scin.Dock = DockStyle.Fill;
AutocompleteMenu autocompleteMenu1 = new AutocompleteMenu(); autocompleteMenu1.SetAutocompleteMenu(scin, autocompleteMenu1); autocompleteMenu1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); autocompleteMenu1.ImageList = null; autocompleteMenu1.Items = new string[] { "<h1></h1>", "<center></center>", "<font color=\"\"></font>", "<div id=\"\"></div>"}; autocompleteMenu1.LeftPadding = 0; autocompleteMenu1.TargetControlWrapper = null; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; autocompleteMenu1.TargetControlWrapper = new ScintillaWrapper(scin); this.Controls.Add(scin); } } |
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: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| partial class Form1 { private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); }
#region Vom Windows Form-Designer generierter Code
private void InitializeComponent() { this.SuspendLayout(); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(766, 355); ScintillaNET.Scintilla scintilla1 = new ScintillaNET.Scintilla(); scintilla1.Name = "scintilla1"; AutocompleteMenuNS.AutocompleteMenu autocompleteMenu1 = new AutocompleteMenuNS.AutocompleteMenu(); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false);
autocompleteMenu1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); autocompleteMenu1.ImageList = null; autocompleteMenu1.Items = new string[] { "<h1></h1>", "<center></center>", "<font color=\"\"></font>", "<div id=\"\"></div>"}; autocompleteMenu1.LeftPadding = 0;
autocompleteMenu1.TargetControlWrapper = new ScintillaWrapper(scintilla1); }
#endregion } |
Christian S. - Mi 13.04.16 21:43
Okay, da kann man doch mal ansetzen :zustimm:
Also erst einmal zu Deinem Code: Du erstellst jetzt pro Programmaufruf jeweils zwei Scintillas und zwei AutoCompleteMenus, nämlich einmal in
Form1_Load und einmal in
InitializeComponent. Das macht keinen Sinn, da solltest Du Dich für eine Stelle entscheiden. Und da über
InitializeComponent drüber steht, dass man den Code nicht mit dem Editor bearbeiten darf, würde ich es in
Form1_Load machen ;)
Zu Deinem Problem bei geänderten Suchvorschlägen: Da kann ich gerade nur raten (diesmal bist Du aber nicht Schuld, ich kann's gerade nur nicht ausprobieren :mrgreen:), aber AutoCompleteMenu geht ja anscheinend auf, wenn ein bestimmter
regulärer Ausdruck [
https://danielfett.de/de/tutorials/tutorial-regulare-ausdrucke/] erfüllt ist (Eigenschaft "SearchPattern"). Standardmäßig scheint das
[\w\.] zu sein und der passt nicht auf die spitzen Klammern, sondern "reagiert" nur auf normale Buchstaben. Du müsstest Da also einen anderen regulären Ausdruck verwenden.
Ralf Jansen - Mi 13.04.16 21:45
Es scheitert am Searchpattern des Menüs der Text in deinem Control wird über einen Regex geparst. Der ist standardmäßig [\w\.] heißt der erkennt nur Buchstaben, Zahlen und Punkt.
Deine Templates enthalten aber kleiner, größer, forwardslash u.s.w. Du mußt also einen passenden Regex der SearchPattern Property zuweisen.
Sind wir mal ehrlich. Die Komponenten die du benutzt sind für deine Fähigkeiten zu komplex und zu wenig dokumentiert. Wir können dich immer wieder einen Millimeter weiterschubsen aber dann wirst du am nächsten Problem stolpern. Du hast eine Chance versuche den Code denn du heruntergeladen hasst tatsächlich zu verstehen. Wenn du das nicht kannst, und da es auch keine wirkliche Doku gibt, dann solltest du die nicht verwenden.
Csharp-programmierer - Do 14.04.16 15:18
Also jetzt funktioniert es auch mit HTML Quelltext. Nun habe ich "nur" noch 2 Fragen:
1) Kann man das ACM auch schon früher aufrufen? Ist ja normal so, dass es bei 4 Zeichen aufgerufen wird, was meiner Meinung nach zu spät ist.
2) Wenn man ein Item im ACM auswählt, welches Event wird dann gefeuert? Ich möchte dann nämlich den Cursor noch richtig platzieren.
Th69 - Do 14.04.16 15:26
Hallo,
wäre es nicht besser, du wendest dich dann direkt an den Entwickler? :?!?:
Christian S. - Do 14.04.16 16:47
Zur ersten Frage hätte ich auf "MinFragmentLength" getippt, aber die ist standardmäßig 2 und nicht 4, ist also vielleicht doch was anderes. :nixweiss:
Zur zweiten Frage: Das Menü hat genau fünf Events, die man sich angucken muss. Davon heißt eines "Selected" und hat die Beschreibung "Occurs after user selected item". :roll:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!