Richtextbox.Text ist leer

  • VB.NET
  • .NET (FX) 4.0

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Richtextbox.Text ist leer

    Hallo,

    ich will mir einen kleinen Editor bauen als MDI-Childfenster innerhalb meiner Anwendung.
    Basis ist eine Richtextbox namens rtbMacro. Das klappt auch soweit, Text ist editierbar, veränderbar über das Clipboard etc. pp.
    Zusätzlich soll es einen Suchen/Ersetzen-Dialog geben, ähnlich wie bei Notepad.
    Der Dialog zur Eingabe des Suchbegriffs (ganz ähnlich wie bei Notepad) ist in einer zusätzlichen Form, die mit .Show(Me) angezeigt wird, wobei Me die Form mit dem Editor ist.
    Aus dem Dialog heraus wird dann die FindText-Methode auf der Form des Editors aufgerufen.
    Das Dumme ist nur, dass für alle Aufrufe aus dem Kontext des Suchen/Ersetzen-Dialogs die Text-Eigenschaft der Richtextbox leer erscheint.
    Darum wird natürlich mein Suchstring auch nie gefunden.
    In der Richtextbox steht aber noch immer das Eingetippte drin, ich kann das auch ändern und ergänzen. Bewege ich mich wieder im Kontext der Editor-Form, ist auch der Inhalt für den Code sichtbar.
    Sicher hat das irgendetwas mit dem Scope zu tun, aber natürlich meckert der Compiler auch nicht.
    Der Code verweist auch immer eindeutig auf das richtige Objekt.
    Alle Debug.Print-Ausgaben zeigen mir, dass bis zum Aufruf des Suchen/Ersetzen-Dialogs die .Text-Eigenschaft der Richtextbox tatsächlich Text enthält.

    Dies ist der Such-Code, den ich aus dem Suchen/Ersetzen Dialog heraus aufrufe. Der Code selbst ist innerhalb der Editor-Form deklariert.

    VB.NET-Quellcode

    1. ' Text suchen im Editor
    2. Friend Sub FindText(ByVal strSearchFor As String)
    3. Dim intPosition As Integer = 0
    4. Dim chrSearch() As Char = strSearchFor.ToCharArray
    5. Debug.Print(" --- FindText --- ")
    6. Debug.Print(Me.rtbMacro.Text)
    7. intPosition = Me.rtbMacro.Find(chrSearch(0)) ' gibt immer -1 zurück, weil .Text-Eigenschaft leer erscheint...
    8. If intPosition >= 0 Then
    9. Me.rtbMacro.SelectionStart = intPosition
    10. Me.rtbMacro.SelectionLength = strSearchFor.Length
    11. Else
    12. Dim strMsg As String = VBQUOTE & strSearchFor & VBQUOTE & " wurde nicht gefunden!"
    13. MessageBox.Show(strMsg, frmSearchDialog.Text)
    14. End If
    15. End Sub


    Was ist da los? Hab ich noch irgendwas vergessen oder gibts da wirklich noch einen Bug?

    Gruß
    Carbonunit
    Hast du schonmal gegoogelt?
    Sowas wie "Richtextbox get Text" oder so?

    Da findet man u.a. sowas:

    C#-Quellcode

    1. TextRange textRange = new TextRange(
    2. // TextPointer to the start of content in the RichTextBox.
    3. rtb.Document.ContentStart,
    4. // TextPointer to the end of content in the RichTextBox.
    5. rtb.Document.ContentEnd
    6. );
    7. // The Text property on a TextRange object returns a string
    8. // representing the plain text content of the TextRange.
    9. return textRange.Text;

    von docs.microsoft.com/en-us/dotne…ontent-from-a-richtextbox

    Lg, Acr0most
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:
    Ich mach VB.NET, nicht C# und aus VB heraus ist für mich die Eigenschaft Document der Richtextbox nicht zugreifbar. Intellisense zeigt sie mir gar nicht erst an. Ich will ja nicht sagen, dass es die nicht gibt, aber ich komme nicht dran.
    Kann natürlich auch eine Versionsfrage sein. Ich benutze VB.NET 2010 Express:
    Microsoft Visual Studio 2010
    Version 10.0.30319.1 RTMRel
    Microsoft .NET Framework
    Version 4.6.01586 RTMRel

    Installierte Version: VB Express

    Microsoft Visual Basic 2010 01012-169-2510015-70488
    Microsoft Visual Basic 2010


    Gegoogelt habe ich natürlich mit den Begriffen, die mir zu meinen Symptomen eingefallen sind, also Richtextbox Kontext, Scope, Text leer. Aber da kam nichts Gescheites.

    Das hier:

    rtbMacro.Document()

    ist bei mir blau-gewellt unterstrichen und das Tooltip dazu sagt:
    "Document" ist kein Member von "System.Windows.Forms.Richtextbox"
    Geht also wohl so nicht oder erst mit VB.NET 2017 oder so.
    Aber die Text-Eigenschaft ist da und da steht auch im Prinzip drin, was drinstehen soll. Nur bei Zugriff aus einem bestimmten Kontext heraus nicht.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Carbonunit“ ()

    Der Code aus Post#1 befindet sich in der DialogFormKlasse oder in der Hauptform mit der RTB? Denn wenn in der DialogFormKlasse, dann kennt diese die RTB aus der Hauptform nicht. Du könntest es so bewerkstelligen, dass der Dialog selber nix ändert, sondern nur die zwei Begriffe (Such- und Ersatz) zurückgibt und die Hauptform sich um den Rest kümmert. Zumindest als Anfang.
    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.
    Den selben Effekt habe ich auch mit einer ganz normalen Textbox, also sicher mache ich da irgendwas falsch, ich komme nur nicht drauf, was das sein könnte. Ich baue nochmal ein Mini-Beispiel zum Nachvollziehen.

    VaporiZed schrieb:

    Der Code aus Post#1 befindet sich in der DialogFormKlasse oder in der Hauptform mit der RTB? Denn wenn in der DialogFormKlasse, dann kennt diese die RTB aus der Hauptform nicht. Du könntest es so bewerkstelligen, dass der Dialog selber nix ändert,…

    Richtig, der Code aus #1 ist auf der Form mit der RTB. Der Suchen/Ersetzen-Dialog soll auch nichts ändern, nur die Suchbegriffe liefern und due entsprechenden Methoden aufrufen. Die Methoden selbst sind dann auch wieder auf der Form mit der RTB.
    @ErfinderDesRades: Der Debugger zeigt mir auch an, dass die Textbox leer ist (also rtbMacro.Text), sowie ich auf der Dialog-Form bin. Am nächsten Breakpoint auf der Editor-Form (die mit der RTB drauf) ist der Text wieder zu sehen. In der Textbox steht er auch die ganze Zeit drin und verschwindet nicht.

    Carbonunit schrieb:

    nur die Suchbegriffe liefern und due entsprechenden Methoden aufrufen. Die Methoden selbst sind dann auch wieder auf der Form mit der RTB.
    Eben nicht. Ich glaub, dass das wieder so ein Punkt ist, bei dem Form-Instanzen durcheinandergewürfelt werden. Der Dialog soll gar keine Funktionen aus dem MainForm aufrufen. Das ist die Aufgabe des MainForms. Zeig mal bitte die Codezeilen, in denen das DialogForm erstellt und aufgerufen wird (nicht nur Show(Me), sondern dazu die komplette Zeile und die Zeilen davor) und wie das DialogForm die Funktionen aus dem HauptForm aufruft.
    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.
    Ja, irgendwas kommt durcheinander, das glaube ich auch.

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class frmMacroEdit
    3. '... mehr Code
    4. ' Deklaration der Form als lokales Objekt
    5. ' Suchen-/Ersetzen -Dialog
    6. Private mfrmSearchDialog As New frmSearchDialog
    7. '... mehr Code
    8. ' Bearbeiten - Suchen - Dieser Menuepunkt ruft die Szchen/Ersetzen Funktionalität auf
    9. Private Sub mnuMacroEditSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuMacroEditSearch.Click
    10. Debug.Print(" --- mnuMacroEditSearch_Click --- ")
    11. Debug.Print(Me.rtbMacro.Text)
    12. OpenSearchReplaceDialog(False).
    13. ' In diesem auskommentierten Code habe ich probiert, ob das überhaupt funktioniert.
    14. ' geht natürlich, solange ich den Kontext meiner Form nicht verlasse...
    15. ' Dim intPos As Integer = FindText("ist", 0, False, False)
    16. 'MessageBox.Show(intPos.ToString)
    17. End Sub
    18. '... mehr Code
    19. ' Suchen-/Ersetzen-Dialog anzeigen
    20. Private Sub OpenSearchReplaceDialog(ByVal blnReplace As Boolean)
    21. Debug.Print(" --- OpenSearchReplaceDialog - Beginn --- ")
    22. Debug.Print(Me.rtbMacro.Text)
    23. With mfrmSearchDialog
    24. If blnReplace Then ' Dialogtitel
    25. .Text = "Suchen und Ersetzen"
    26. Else
    27. .Text = "Suchen"
    28. End If
    29. .cmdReplace.Visible = blnReplace ' Ersetzen-Button
    30. .cmdReplaceAll.Visible = blnReplace ' Alle Ersetzen Button
    31. .lblReplace.Visible = blnReplace ' Beschriftung für ReplaceWith-Textbox
    32. .txtReplaceWith.Visible = blnReplace ' Textbox mit dem Begriff, der ersetzt werden soll
    33. .Show(Me)
    34. End With
    35. Debug.Print(" --- OpenSearchReplaceDialog - Ende --- ")
    36. Debug.Print(Me.rtbMacro.Text)
    37. End Sub
    38. '... mehr Code
    39. End Class


    Die Debug-Ausgaben hier zeigen noch den Inhalt der Textbox

    Dieser Button auf dem Dialog ruft die Methode FindText auf (Code siehe Beitrag #1):

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class frmSearchDialog
    3. '... mehr Code
    4. Private Sub cmdSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSearch.Click
    5. Dim intLastPosition As Integer = frmMacroEdit.LastPosition
    6. Debug.Print(" --- frmSearchDialog.cmdSearch_Click --- ")
    7. Debug.Print(frmMacroEdit.rtbMacro.Text)
    8. frmMacroEdit.LastPosition = frmMacroEdit.FindText(txtSearchFor.Text, intLastPosition, chkCaseMatters.Checked, chkWholeWord.Checked)
    9. End Sub
    10. '... mehr Code
    11. End Class

    Die Debug-Ausgabe hier zeigt schon an, dass die Text-Eigenschaft leer zu sein scheint.

    @ErfinderDesRades: Bewußt mache ich hier nichts mit Threads. Also ich habe keinen Code geschrieben, der irgendeinen zusätzlichen Thread anlegt oder ausführt.

    Carbonunit schrieb:

    Also ich habe keinen Code geschrieben, der irgendeinen zusätzlichen Thread anlegt oder ausführt.
    Dassis gut :thumbup:

    Dann vermute ich (naja - halte es für nicht ausgeschlossen), dass du in frmSearchDialog irgendwo eine Zeile zu stehen hast, wie

    VB.NET-Quellcode

    1. Private frmMacroEdit As New frmMacroEdit
    wenn dem so ist, lösch sie erstmal und probier nochmal.
    (wäre zwar super-Quick And Dirty, und sollte keinesfalls so bleiben, aber auf einen Doktor hört man besser, wenner erstmal schnelle Linderung bewirken kann. ;) )
    Könnte man annehmen, denn der Zugriff als solcher Funktioniert ja.
    Da könnte es schon sein, dass ich irgendwie eine andere Instanz der Form erzeugt habe, die jetzt natürlich keine Daten enthält, und dann darauf zugreife.
    Hier der komplette Code von frmSearchDialog, den ich zu verantworten habe:

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class frmSearchDialog
    3. Private Sub cmdDone_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDone.Click
    4. Me.Hide()
    5. End Sub
    6. Private Sub txtSearchFor_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearchFor.TextChanged
    7. cmdSearch.Enabled = CBool(txtSearchFor.Text.Length)
    8. End Sub
    9. Private Sub txtReplaceWith_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtReplaceWith.TextChanged
    10. cmdReplace.Enabled = CBool(txtReplaceWith.Text.Length)
    11. cmdReplaceAll.Enabled = CBool(txtReplaceWith.Text.Length)
    12. End Sub
    13. Private Sub cmdSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSearch.Click
    14. Dim intLastPosition As Integer = frmMacroEdit.LastPosition
    15. Debug.Print(" --- frmSearchDialog.cmdSearch_Click --- ")
    16. Debug.Print(frmMacroEdit.rtbMacro.Text)
    17. frmMacroEdit.LastPosition = frmMacroEdit.FindText(txtSearchFor.Text, intLastPosition, chkCaseMatters.Checked, chkWholeWord.Checked)
    18. End Sub
    19. Private Sub cmdReplace_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReplace.Click
    20. End Sub
    21. Private Sub frmSearchDialog_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
    22. Debug.Print(" --- frmSearchDialog_Activated --- ")
    23. Debug.Print(frmMacroEdit.rtbMacro.Text)
    24. End Sub
    25. End Class


    Da ist aber keine neue Instanz deklariert...
    Leider kann ich es nicht nachbauen, da scheint noch was unerkannt zu sein:
    Hauptform:

    VB.NET-Quellcode

    1. Private TestForm As New Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. TestForm.Show(Me)
    4. End Sub
    5. Private Sub BtnEnd_Click(sender As Object, e As EventArgs) Handles BtnEnd.Click
    6. Me.Close()
    7. End Sub


    Suchform:

    VB.NET-Quellcode

    1. Public Class FrmSearchDialog
    2. Private Sub cmdDone_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDone.Click
    3. Me.Hide()
    4. End Sub
    5. Private Sub FrmSearchDialog_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
    6. Console.WriteLine(" --- frmSearchDialog_Activated --- ")
    7. Console.WriteLine(FrmMain.RichTextBox1.Text)
    8. End Sub
    9. End Class

    Wenn man davon absieht, dass ein SubForm (also FrmSearchDialog) nichts von einem anderen Form einfach mal so erfahren sollte, sondern per Event brav nach Infos fragt, erhalte ich den RTB.Text des HauptForms. Ich bin gerade etwas verwirrt, was ich bei Deinem Code übersehen habe.
    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.
    @VaporiZed: Danke fürs Nachbauen, ich leg das auch erstmal beiseite, manchmal ist der Kopf wie vernagelt. War aber nicht untätig, habe die TODOs von 53 auf 36 runtergebracht. In einem weiteren Modul ist jetzt der Deppen-Namespace draußen und es compiliert auch brav mit Option Strict On.
    Sollte ich rausfinden, woran das liegt, dass die text-Eigenschaft leer erscheint, kommt die Lösung natürlich hier rein. wem noch was ein- oder auffällt: Immer her damit.
    Ich hab Nachtschicht gemacht, kann sowieso nicht schlafen. Debug Print sagt, dass das Handle der Form (also frmMacroEdit) auf die ich von meinem SearchDialog aus zugreife, ein anderes ist, als von der Form, auf der das RTB ist, wo ich den Text eingegeben habe.
    Also habe ich da zwei verschiedene Instanzen der selben Form, eine mit Text im RTB und eine ohne.
    Was mir derzeit wiederum nur bei Thread bekannt ist. Bzgl. FormHandle hatte ich auch schon nachgeschaut. In der von mir geposteten Variante ist dieses für das HauptForm (abgefragt in beiden Forms) identisch. Kannst Du eine Kopie Deines Projektes so stark inhaltlich zusammenschmelzen, dass beide Forms bleiben, der Effekt bleibt, aber sonst nichts (relevantes) übrig ist und dieses Testprojekt hier per [Erweiterte Antwort] hochladen?
    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.
    @Carbonunit Wie kommt denn der Text in die RTB rein?
    Da solltest Du mal nen Haltepunkt drauf setzen und das für die beiden Fälle untersuchen. Lerne zu debuggen, gugst Du Debuggen, Fehler finden und beseitigen
    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,
    die anderen haben es ja bereits gesagt, du greifts aus der Suchform auf die Hauptform zu und die ist in dem Moment aber nicht die Form, die du meinst.
    Anderer Ansatz:
    2 Formen, 1 Hauptform, 1 Suchform.
    Hauptform hat ne RTB und nen Button "Suchen/Ersetzen":

    VB.NET-Quellcode

    1. Public Class HauptForm
    2. Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click
    3. Using f As New SuchenErsetzenForm
    4. If f.ShowDialog() = DialogResult.OK Then
    5. Dim s As String = f.SearchText 'hier steht der Suchtext drin
    6. Dim r As String = f.ReplaceText 'hier steht der ReplaceText drin
    7. End If
    8. End Using
    9. End Sub
    10. End Class

    Suchform hat 2 Textboxen (Suchen, Ersetzen) und 2 Buttons "OK" und "Cancel"
    Bei der Suchform in den Eigenschaften ist AcceptButton und CancelButton gesetzt.

    VB.NET-Quellcode

    1. Public Class SuchenErsetzenForm
    2. Private _searchText As String
    3. Public Property SearchText() As String
    4. Get
    5. Return _SearchText
    6. End Get
    7. Set(ByVal value As String)
    8. _SearchText = value
    9. End Set
    10. End Property
    11. Private _replaceText As String
    12. Public Property ReplaceText() As String
    13. Get
    14. Return _replaceText
    15. End Get
    16. Set(ByVal value As String)
    17. _replaceText = value
    18. End Set
    19. End Property
    20. Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
    21. _searchText = txtSuche.Text
    22. _replaceText = txtReplace.Text
    23. Me.Close()
    24. End Sub
    25. End Class


    durch die 2 Propertys hast Du dann in deiner Hauptform vollen Zugriff auf den Suchtext und den ReplaceText und kannst dies innerhalb der Hauptform für die RTB verarbeiten.
    "Hier könnte Ihre Werbung stehen..."
    @VaporiZed: Eindampfen aufs Wesentliche mit erhaltener Nachvollziehbarkeit versuch ich mal übers Wochenende.
    @RodFromGermany: Den Text in der einen Instanz habe ich selbst eingetippt. Wie ich in der anderen Instanz irgendwas debuggen soll, weiß ich auch nicht so recht. Das Problem wird beim Öffnen des Dialogs irgendwie entstehen. Schon im Activated-Event des Dialogs wird die Form mit dem anderen Handle angezeigt, wenn ich über den Namen der aufrufenden Form (frmMacroEdit) darauf zugreife. Frage ich hier Owner.ActiveMDIChild.Handle ab, wird das rchtige Handle ausgegeben. Eigentlich will ich aus dem Dialog heraus auch nicht viel mit der Owner-Form machen, nur Methoden daraus aufrufen. Diese Aufrufe landen aber in einer anderen Instanz, die meinen eingetippten Text nicht kennt.
    @MichaHo: Der Dialog soll während der Suche offen bleiben, so wie z.B. im VB-Editor oder bei Notepad. Bei deinem Vorschag wird der Dialog gleich wieder geschlossen und dann wird gesucht.

    Beim Antwort Schreiben ist es mir dann gedämmert. Wer schon weiß, wo das richtige Handle ist, der hat es ja recht einfach, also flugs dieses im Click-Event des Suchbuttons auf der Dialogform deklariert:

    VB.NET-Quellcode

    1. Dim intLastPosition As Integer = 0
    2. Dim frmOwner As frmMacroEdit = CType(Me.Owner.ActiveMdiChild, frmMacroEdit) ' Muss sein wegen Option Strict On
    3. Debug.Print(" --- frmSearchDialog.cmdSearch_Click --- ")
    4. Debug.Print("frmOwner.Handle = " & frmOwner.Handle.ToString)
    5. Debug.Print("frmOwner.rtbMacro.Text = " & frmOwner.rtbMacro.Text)
    6. Debug.Print("Me.Owner.ActiveMdiChild.Handle =" & Me.Owner.ActiveMdiChild.Handle.ToString)
    7. With frmOwner
    8. .LastPosition = .FindText(txtSearchFor.Text, intLastPosition, chkCaseMatters.Checked, chkWholeWord.Checked)
    9. End With


    Siehe da, schon wird mein Text gefunden und markiert. Letzteres zwar erst nach Schließen des Dialogs, aber das wird daran liegen, welches Fenster gerade den Focus hat.
    Drüber reden hilft auf jeden Fall, danke euch, ich markier das dann mal als erledigt