WPF: Suchwort in Richtextbox in der Mitte (vertikal) der RTB zentrieren

  • WPF

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von Translating-IT.

    WPF: Suchwort in Richtextbox in der Mitte (vertikal) der RTB zentrieren

    Hallo,

    Ich versuche in WPF einen bestimmten String in einer RTB zu suchen und diesen dann auszuwählen (und evtl. den Cursor in der Zeile platzieren - oder ist das dann doppelt gemoppelt?). Die Zeile mit dem ausgewählten Text soll dann in der Mitte der RTB angezeigt werden (vorausgesetzt, dass es mehr Zeilen gibt als die RTB hoch ist).

    Die Startposition des Strings zu finden ist kein Problem.

    VB.NET-Quellcode

    1. Dim str_rtbtext As String = New TextRange(rtb_targettext.Document.ContentStart, rtb_targettext.Document.ContentEnd).Text
    2. Dim int_stringpos As Integer = str_rtbtext.IndexOf("Suchstring")


    Nur scheine ich mich für den Rest bei den Suchmaschinen blöd anzustellen, da ich nicht wirklich etwas dazu finde. Für eine nromale Textbox habe ich es hinbekommen. RTB ist da zickiger. ;)

    An sich dürfte es ähnlich einer Suchfunktion sein, dazu nur halt das Zentrieren noch. Aber ich finde für beides seit Stunden nicht wirklich was brauchbares.

    Bei der TB muss ich die Position finden, die Höhe der Box berechnen, diese durch die Höhe der Zeilen teilen (= Ergebnis) und dann per ScrollToLine mit entsprechenden Werten abzgl. dem gerundeten Ergebnis /2 anzeigen lassen …

    LG,
    Pascal
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Translating-IT“ ()

    Translating-IT schrieb:

    Nur scheine ich mich für den Rest bei den Suchmaschinen blöd anzustellen
    Suchstring: vb.net richtextbox text zentrieren
    Link: docs.microsoft.com/de-de/dotne…ionalignment?view=net-5.0
    Code:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. ' Clear all text from the RichTextBox;
    3. RichTextBox1.Clear()
    4. ' Set the foreground color of the text.
    5. RichTextBox1.SelectionColor = Color.Red
    6. ' Set the alignment of the text that follows.
    7. RichTextBox1.SelectionAlignment = HorizontalAlignment.Center
    8. ' Set the font for the text.
    9. RichTextBox1.SelectionFont = New Font("Lucinda Console", 12)
    10. ' Set the text within the control.
    11. RichTextBox1.SelectedText = "This text is centered using the SelectionAlignment property."
    12. End Sub
    Output:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo Rod,

    nein, leider nicht. Es geht nicht darum ein Wort zu zentrieren (aka formatieren) sondern in die Mitte der RTB zu zentrieren. z. B. ich habe eine RTB die 20 Zeilen anzeigt. Der Text ist in Zeile 25. Diese Zeile soll nun in der RTB auf Sichthöhe Zeile 10 (je nachdem wie gerundet wird) angezeigt werden, also recht mittig in der RTB.

    Edit: Ich habe noch den Titel ergänzt, damit klar ist, dass wir in WPF unterwegs sind.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Translating-IT schrieb:

    nein, leider nicht.
    Was macht Deine WPF-RTB mit meinem WinForm-Code?
    Poste mal einen Screenshot.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So wie ich das sehe (ohne zu testen, da ich den Code nicht zur Hand habe), ein Alignment mittig (bitte mich zu korrigieren, wenn ich falsch liege). Aber ich will kein Aligment, sondern die Zeile mit dem ausgewählten Text in der mittleren Zeile der RTB anzeigen lassen (in die Mitte gescrollt - was natürlich nur geht, wenn mehr Zeilen als die maximale Höhe der RTB vorhanden sind). Ich habe aber gesehen, dass ich im Titel horizontal mit vertikal verwechselt habe und dies korrigiert.

    Wie ich ein Alignment machen oder den Text formatieren kann, ist nicht schwer mit Google zu finden. Da gibt es tausende Beispiele.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Translating-IT schrieb:

    in der mittleren Zeile der RTB anzeigen lassen
    klingt nach VERTIKAL zentrieren, im Gegensatz zum Thread-Titel.
    Momentan verstehe ich Bahnhof.
    Poste mal ein Bild, wie es sein soll und benenne klar die Randbedingungen (Zeilenzahl, Umbruch, ...).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    klingt nach VERTIKAL zentrieren, im Gegensatz zum Thread-Titel.


    Stimmt. Sorry, war gestern vom Arbeiten schon ganz kirre, als ich den Titel geändert habe. Hab's wieder zurückgeändert.

    Zeilenanzahl unbekannt, da Größe der RTB veränderbar.
    Umbruch? Meinst TextWrap? Ist aktiviert.

    Beispiel zur Einfachheit in Excel gebastelt. Wenn jetzt eine andere Zeile ausgewählt würde, würde sich die Ansicht so verschieben (scrollen), dass diese Zeile "genau" in der Mitte angezeigt wird.


    Bilder
    • aktive Zeile mittig.png

      26,41 kB, 1.475×713, 85 mal angesehen
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.
    Wegen der vielen nachträglichen Änderungen bin ich erst mal draußen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    WPF: Suchwort in Richtextbox in der Mitte (vertikal) der RTB zentrieren[/url]']Wegen der vielen nachträglichen Änderungen bin ich erst mal draußen.


    An sich ist es nur eine Präzisierung im Titel und eine Änderung gewesen, die dann wieder Rückgängig gemacht wurde, aber ok. Die Fragestellung bzw. Problemerörterung selbst hat sich dadurch nicht verändert.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.
    @Translating-IT Ich präsentiere Dir die perefekte Lösung für das horizontale Zentrieren entsprechend Deiner Beschreibung.
    OK.
    Probier mal .ScrollToCaret(), wenn der Eingabecursor an der geeigneten Position steht.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo Rod,

    das habe ich nur in Kombination mit Winforms gefunden. Funktioniert leider nicht in WPF.

    Heute habe ich noch ScrolltoVertivalOffset gefunden (für WPF), aber leider hapert es noch mit dem Ermitteln der Textpointer für die Positionsangaben.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Translating-IT schrieb:

    Funktioniert leider nicht in WPF.
    Sorry, ich hab von WPF keine Ahnung (das war auch eine wesentliche Änderung).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ok, danke trotzdem.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.
    Ok, ich bin nun etwas vorangekommen und schaffe es Text auszuwählen und dorthin zu scrollen. Es gibt nur ein paar kleine Problemchen. Der ausgewählte Text liegt knapp hinter dem gesuchten string und die Scrollposition liegt ganz am Ende von der RTB. Aber zumiindest ist die Auswahl sichtbar.

    Hier meinen Text:

    VB.NET-Quellcode

    1. Public Function FindTextInRange(ByVal searchRange As TextRange, ByVal searchText As String) As TextRange
    2. Dim offset As Integer = searchRange.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase)
    3. If offset < 0 Then Return Nothing ' Not found
    4. Dim start = GetTextPositionAtOffset(searchRange.Start, offset)
    5. Dim result As TextRange = New TextRange(start, Me.GetTextPositionAtOffset(start, searchText.Length))
    6. Return result
    7. End Function
    8. Private Function GetTextPositionAtOffset(ByVal position As TextPointer, ByVal characterCount As Integer) As TextPointer
    9. While position IsNot Nothing
    10. If position.GetPointerContext(LogicalDirection.Forward) = TextPointerContext.Text Then
    11. Dim count As Integer = position.GetTextRunLength(LogicalDirection.Forward) + Environment.NewLine.Length '+ Environment.NewLine.Length hinzugefügt, um auch mögliche Zeilenumbrüche zu berücksichtigen, damit die Position genauer bestimmt wird.
    12. If characterCount <= count Then
    13. Return position.GetPositionAtOffset(characterCount)
    14. End If
    15. characterCount -= count
    16. End If
    17. Dim nextContextPosition As TextPointer = position.GetNextContextPosition(LogicalDirection.Forward)
    18. If nextContextPosition Is Nothing Then Return position
    19. position = nextContextPosition
    20. End While
    21. Return position
    22. End Function
    23. Dim searchRange As TextRange = New TextRange(rtb_targettext.Document.ContentStart, rtb_targettext.Document.ContentEnd)
    24. Dim foundRange As TextRange = FindTextInRange(searchRange, "hunn keen")
    25. rtb_targettext.Selection.Select(foundRange.Start, foundRange.End)
    26. Dim screenpos As Rect = rtb_targettext.Selection.Start.GetCharacterRect(LogicalDirection.Forward)
    27. Dim offset As Double = screenpos.Top + rtb_targettext.VerticalOffset
    28. rtb_targettext.ScrollToVerticalOffset(offset - (rtb_targettext.ActualHeight / 2))


    Edit:

    Im Anhang sieht man ganz unten die aktuelle Auswahl, es sollte aber der rot eingekreiste Text ausgewählt sein. und die Zeile mit der Auswahl sollte eigentlich in der Mitte der RTB angezeigt werden, nicht am Ende.

    Edit 2: Ok, einen Fehler habe ich gefunden: wenn man die falsche Zeile im Dropdown der Vorschläge anklickt und Horizontal statt Vertikal einsetzt, kann er die Mitte nicht finden. :whistling: ScrollToHorizontalOffset mit ScrollToVerticalOffset im Code ersetzt.

    Die Mitte ist nun gefunden, fehlt nur noch die Fehlerkorrektur bei der Suche zu eruieren.

    Edit 3: Code an das finale Ergebnis angepasst.

    Bilder
    • problemchen zu auswahl scrollen.png

      75,27 kB, 1.152×1.002, 73 mal angesehen
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Translating-IT“ ()

    Hallo @Nofear23m,

    Fällt Dir eventuell etwas auf, warum die Position des gefundenen Texts so weit daneben liegt?

    LG,
    Pascal
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.
    Ok, ich habe den Schuldigen gefunden. Wenn die RTB befüllt wird, wird zu jeder Zeile ein Zeilenumbruch per " + Environment.NewLine" hinzugefügt. Wenn ich den weglasse, findet das Skript den Text punktgenau. Nur leider ist dann der gesamte Text eine ganze Wurst und "schwer" zu lesen, bzw. rauszufinden, wo man dran ist.

    Wie kann ich das anders lösen, dass ich immer noch eine neue Zeile nach jedem eingefügten String habe, und er die richtige Position findet?
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.
    Du könntest versuchen, bei position.GetTextRunLength(LogicalDirection.Forward) noch ein + 1 oder + 2 oder allgemein + Environment.NewLine.Length dranzuhängen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hi @VaporiZed,

    Ja, + Environment.NewLine.Length anzuhängen funktioniert, unabhängig davon ob bei einem String ein Zeilenumbruch angehängt wird oder nicht.

    Edit: den Code weiter oben an das Endergebnis angepasst.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.