Discussion:
Scrollen in Richtextbox
(zu alt für eine Antwort)
Oliver Braun
2006-03-14 11:34:23 UTC
Permalink
Hallo, jetzt brauche ich Hilfe durch Fachleute:

Ich habe die Windows-eigene RichTextBox auf einem Formular und fülle sie mit
Logging-Texten aus Komponenten. Die Texte werden einfach hintereinander
gehängt:

richTextBox.Text += "Neuer Text" + Environment.NewLine;

Soweit so gut. Dann wollte ich, dass die RichTextBox bei Bedarf scrollt,
dann nämlich, wenn eine CheckBox angehakt ist:

if (checkBoxAutoscroll.Checked)
{
richTextBox.SelectionStart = richTextBox.Text.Length;
richTextBox.SelectionLength=0;
richTextBox.Focus(); // to make next command (ScrollToCaret) work !
richTextBox.ScrollToCaret();
Application.DoEvents();
}

Jetzt meine Probleme:

- Wenn ich die Checkbox deaktiviere, springt die Textmarke in der
RichTextBox immer an den Anfang und bleibt nicht da stehen, wo ich sie
zuletzt hingesetzt habe.
- Wenn der Text eine bestimmte Größe erreicht hat, kommt es zu ganz
seltsamen Effekten beim Scrollen. Eigentlich dachte ich, mit der RichTextBox
hätte ich keine Größenprobleme des Inhalts wie bei der Textbox, aber
vielleicht funktioniert dann die Text.Length-Abfrage nicht mehr richtig.

Kennt jemand einen besseren Ansatz, mein Feature zu realisieren? Oder hat
jemand konkrete Tipps für den gewählten Weg?
Vielen Dank !
Hans-Heinrich Breuer
2006-03-14 14:27:59 UTC
Permalink
Hallo Oliver,
Post by Oliver Braun
...
if (checkBoxAutoscroll.Checked)
{
richTextBox.SelectionStart = richTextBox.Text.Length;
richTextBox.SelectionLength=0;
richTextBox.Focus(); // to make next command (ScrollToCaret) work !
nimm diesen Befehl heraus (ScrollToCaret funktioniert auch ohne). Dann wird
die Einfügemarke auch nicht geändert.


Gruß,

Heiner.
Herfried K. Wagner [MVP]
2006-03-14 15:41:00 UTC
Permalink
Hallo Hans-Heinrich!
Post by Hans-Heinrich Breuer
Post by Oliver Braun
richTextBox.SelectionStart = richTextBox.Text.Length;
richTextBox.SelectionLength=0;
richTextBox.Focus(); // to make next command (ScrollToCaret) work !
nimm diesen Befehl heraus (ScrollToCaret funktioniert auch ohne). Dann
wird die Einfügemarke auch nicht geändert.
Nicht bei der RichTextBox unter .NET 1.*, sondern nur bei der TextBox.

Eventuell auch brauchbar: PInvoke mit 'SendMessage' + 'WM_VSCROLL' (Vorlage
in VB.NET):

Hinzufügen und Sichtbarmachen einer Zeile in einem RichTextBox-Steuerelement
<URL:http://dotnet.mvps.org/dotnet/faqs/?id=richtextboxscrolltobottom&lang=de>
--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>
Hans-Heinrich Breuer
2006-03-14 18:13:49 UTC
Permalink
Hallo Herfried,
Post by Herfried K. Wagner [MVP]
Post by Hans-Heinrich Breuer
...
nimm diesen Befehl heraus (ScrollToCaret funktioniert auch ohne). Dann
wird die Einfügemarke auch nicht geändert.
Nicht bei der RichTextBox unter .NET 1.*, sondern nur bei der TextBox.
Wie kommst du da drauf?

Ich habe es gerade unter .NET 1.0 und .NET 2.0 ausprobiert. Unter beiden
Versionen funktioniert es hier tadellos. (ScrollToCaret _ohne_ Focus)

Was genau meintest du, was nicht unter .NET 1.* geht?

Gruß,
Heiner.
Herfried K. Wagner [MVP]
2006-03-14 18:38:01 UTC
Permalink
Hallo Hans-Heinrich!
Post by Hans-Heinrich Breuer
Post by Herfried K. Wagner [MVP]
Post by Hans-Heinrich Breuer
nimm diesen Befehl heraus (ScrollToCaret funktioniert auch ohne). Dann
wird die Einfügemarke auch nicht geändert.
Nicht bei der RichTextBox unter .NET 1.*, sondern nur bei der TextBox.
Wie kommst du da drauf?
Ich habe es gerade unter .NET 1.0 und .NET 2.0 ausprobiert. Unter beiden
Versionen funktioniert es hier tadellos. (ScrollToCaret _ohne_ Focus)
Was genau meintest du, was nicht unter .NET 1.* geht?
Hinterlege folgenden Code im 'Click'-Ereignis einer Schaltfläche:

\\\
this.RichTextBox1.AppendText("Hello World\n");
this.RichTextBox1.SelectionStart = this.RichTextBox1.TextLength;
this.RichTextBox1.ScrollToCaret();
///

Mehrfaches Klicken der Schaltfläche führt nicht dazu, dass immer die letzte
Zeile sichtbar ist (.NET Framework 1.1 unter Windows XP Professional SP2).
--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>
Hans-Heinrich Breuer
2006-03-14 18:59:18 UTC
Permalink
Hallo Herfried,
Post by Herfried K. Wagner [MVP]
...
\\\
this.RichTextBox1.AppendText("Hello World\n");
this.RichTextBox1.SelectionStart = this.RichTextBox1.TextLength;
this.RichTextBox1.ScrollToCaret();
///
Mehrfaches Klicken der Schaltfläche führt nicht dazu, dass immer die
letzte Zeile sichtbar ist (.NET Framework 1.1 unter Windows XP
Professional SP2).
Kann ich leider nicht ausprobieren, da ich keine Studio Version 2003 habe.
Unter .NET 2.0 klappt es allerdings _tadellos_.

Jedoch habe ich wohl vorhin zu vorschnell den Test unter .NET 1.0 gemacht.
Dies funktioniert entgegen meiner Behauptung nämlich nicht.

Gruß,

Heiner.
Hans-Heinrich Breuer
2006-03-14 20:11:24 UTC
Permalink
Hallo Oliver,
Post by Oliver Braun
...
if (checkBoxAutoscroll.Checked)
{
richTextBox.SelectionStart = richTextBox.Text.Length;
richTextBox.SelectionLength=0;
richTextBox.Focus(); // to make next command (ScrollToCaret) work !
richTextBox.ScrollToCaret();
Application.DoEvents();
}
Unter .NET 2.0 entferne die Zeile

richTextBox.Focus();

Unter .NET 1.0 hänge einen else-Zweig an:

if (checkBoxAutoscroll.Checked)
{
richTextBox.SelectionStart = richTextBox.Text.Length;
richTextBox.SelectionLength=0;
richTextBox.Focus(); // to make next command (ScrollToCaret) work !
richTextBox.ScrollToCaret();
Application.DoEvents();
} else {
// _hier Focus weiterreichen_
checkBoxAutoscroll.Focus(); // oder ein anderes Control (!= richTextBox)
} // else-if (...)

Unter beiden Versionen springt nach dem Ändern der Checkbox die RichTextBox
_nicht_ zur ersten Zeile zurück, sondern verbleibt an der zuletzt gezeigten
Zeile.

Trifft dies nun das von dir gewünschte Verhalten?

Gruß,
Heiner.
Frank Dzaebel
2006-03-14 21:46:03 UTC
Permalink
Hallo Hans-Heinrich,
Post by Oliver Braun
richTextBox.Focus(); // to make next command (ScrollToCaret) work !
ist nicht so sauber. Es hat Seiteneffekte.
Ein Auffüllen des Textes darf den Fokus nicht neu setzen.
Besser hier IMHO etwa folgender Ansatz ohne überschriebene WndProc:
http://groups.google.de/group/microsoft.public.de.german.entwickler.dotnet.csharp/msg/4713bf40f0eb060b


ciao Frank
--
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET
Loading...