Laden...

eigene TextBox: Text mit Mouse selektieren...

Erstellt von Animal21 vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.912 Views
A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 13 Jahren
eigene TextBox: Text mit Mouse selektieren...

Hallo leute...

Da ich den umgang beim Design der Standard TextBox leid bin, wollte ich meine eigene schreibe:

  • Die TextBox erst von UserControl

Jedoch hat sich die Sache in bestimmten Pukten komplexter ergeben als gedacht 😦

Was funktioniert:

  • Zeichne die TextBox komplett selber, also

        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);

und über


    protected override void WndProc(ref Message m) {
        base.WndProc(ref m);
        if(m.Msg == (int)WM_COMMANDS.WM_PAINT) { ...}
  • Text eingeben, mit Pfeiltasten durchnavigieren, löschen mit 'BackSlash' und 'Del', sowie 'Pos1', 'End' un eine Redo/Undo Funktion sind fertig...
  • das markieren von Text indem man die Pfeiltasten benutz, also Pfeil+Shift bzw. Pfeil + Shift + Strg und darauffolgendes löschen, überschreiben etc. sind kein problem...

Mein momentanes Hauptproblem ist es, einen gewünschten Text per Maus zu selektieren...

Folgendes:
Meine Zeichen sind sogenannte 'TextChar':

public class TextChar: IDisposable {
    private static int counter;
    private int id;
    private int index;
    private int left;
    private int charWidth;
    private bool selected;
    private char key;

    public TextChar(char key, bool selected) {
        this.id = counter++;
        this.key = key;
        this.selected = selected;
    }

    public int ID { get { return id; } }
    public int Index { get { return index; } internal set { index = value; } }
    public char Key { get { return key; } set { key = value; } }
    public int Left { get { return left; } set { left = value; } }
    public int CharWidth { get { return charWidth; } set { left = value; } }
    public bool Selected { get { return selected; } internal set { selected = value; } }

    public void ReCalcCharWidth(Graphics g, Font font) {        
        //...
    }
    public void Dispose() {
        //...
    }
    private Rectangle MeasureString(String strText, Font font, Graphics gDevice) {
        //...
    }
}

<-- Diese werden in einer Liste (

TextCharCollection : IList<TextChar>

) gespeichert un dann wie auch immer benutzt um zu zeichnen, text hinzuzufügen, zu selektieren, was auch immer.

Der BlinkerCursor is einfach nur ein index, welcher halt die aktuelle TextChar Position speichert und dann an der stelle gezeichnet wird...


    protected override void OnMouseDown(MouseEventArgs e) {
        //...
   }

Hier wird der BlinkerIndex neuberechnet, abhängig von der Mausposition und anhand der 'Left' bzw. 'CharWidth' Propertie kann ein RecTangle erzeugt werden und geprüft werden, ob die Mouse da drin is...


    protected override void OnMouseMove(MouseEventArgs e) {
         //...
    }

Hier sollte nun das eigentliche selektieren geschehen, un den BlinkerIndex neu zu setzen, klappt hier auch wunderbar, nur das Markieren des Textes will nicht wie ich:

        if(mouseDown) {
            mousePos = e.Location;
            foreach(TextChar tc in myText) {
                Rectangle recCheck = new Rectangle(tc.Left, 0, tc.CharWidth, this.Height);
                if(recCheck.Contains(mousePos)) {
                    if(BlinkerIndex > -1 && BlinkerIndex + 1 < myText.Count) {
                        int mouseBlinkerDif = mousePos.X - (tc.Left + tc.CharWidth);

                        //bool left = new Rectangle(recCheck.X + (int)(recCheck.Width / 2), recCheck.Y, (int)(recCheck.Width / 2), recCheck.Height).Contains(mousePos);
                        Console.WriteLine("mousePos.X: " + mousePos.X);
                        Console.WriteLine("myText[tc.Index + 1].Left: " + myText[tc.Index + 1].Left);
                        bool go = mousePos.X >= myText[tc.Index + 1].Left - 3;

                        if(go) {
                            BlinkerIndex = tc.Index;
                            [B]tc.Selected = !tc.Selected;[/B]
                        } else { }

                        Console.WriteLine("Invalidate : OnMouseMove");
                        Invalidate(recBlinker);
                        break;
                    }
                }
            }
        }

der text wird nur teilweise un lückenhaft selektiert, ...

mfg
ani

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

Du solltest immer nur das erste und letzte Element der Selektion bestimmen und dazwischen alle Zeichen selektieren.

Andernfalls kanst Du verschiedene Probleme bekommen:

  • bist Du mit der Maus zu schnell, kann es sein, daß zwischen 2 Events ein ganzes Zeichen übersprungen wird.
  • bist Du mit der Maus zu langsam, bekommst Du bei aufeinanderfolgenden Eventsdas selbe Zeichen, und in Deiner aktuellen Versin schaltest Du die elektion beim 2. Mal durch tc.Selected = !tc.Selected; wieder aus.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 13 Jahren

sorry, hab das prohekt einn bissl ruhn lassen müssen, war krank 😦(

habs geschafft, dass wenn ich die maus nach rechts ziehe, das ganze schön selektiert wird (zittert zwar alles, aber das prob lös ich später ^^)

weis nur nicht ganz, wie ich es realisieren soll, damit die buchstaben auch markiert werden, wenn ich nach links ziehe...

PS: die ganze "ich bastln mir meine eigene textbox"-sache is schwerer als gedacht 😦

edit:
hab die vorgehnsweise vergessen xD:
bei MouseDown wird die position gemerkt (also bei welchem char-index wir sind) ("firstChar") und bei MouseMove jeweils welche weiterhin markiert werden ("lastChar") und am ende von MouseMove werden alle buchsten von "firstChar" bis "lastChar" markiert.