Get und Set einer RTB (xceed) bei Änderung auslösen?

  • WPF

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

    Hallo Sascha (@'Nofear23m'),

    So, hab gestern mal wieder etwas Ziet gehabt und die OC wieder wie folgt eingebunden (auskommentiert):

    XAML:

    XML-Quellcode

    1. <DataGridTextColumn Header="Id" Binding="{Binding URID}" Width="Auto"></DataGridTextColumn>
    2. <DataGridTemplateColumn Header="source_segment" Width="50*">
    3. <DataGridTemplateColumn.CellTemplate>
    4. <DataTemplate>
    5. <toolkit:RichTextBox
    6. x:Name="rtb" VerticalScrollBarVisibility="Auto" Text="{Binding SOURCE,
    7. Mode=TwoWay, UpdateSourceTrigger=LostFocus}">
    8. <myCustomFormatter:MyFormatter />
    9. </toolkit:RichTextBox.TextFormatter>-->
    10. <toolkit:RichTextBox.TextFormatter>
    11. <toolkit:PlainTextFormatter />
    12. </toolkit:RichTextBox.TextFormatter>
    13. </toolkit:RichTextBox>
    14. </local:RichTextBoxHelper>-->
    15. </DataTemplate>
    16. </DataGridTemplateColumn.CellTemplate>
    17. <DataGridTemplateColumn.CellStyle>
    18. <Style>
    19. <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
    20. </Style>
    21. </DataGridTemplateColumn.CellStyle>
    22. </DataGridTemplateColumn>
    23. <DataGridTemplateColumn Header="target_segment" Width="50*">
    24. <DataGridTemplateColumn.CellTemplate>
    25. <DataTemplate>
    26. <toolkit:RichTextBox
    27. x:Name="rtb" VerticalScrollBarVisibility="Auto" Text="{Binding TARGET,
    28. Mode=TwoWay, UpdateSourceTrigger=LostFocus}">
    29. <toolkit:RichTextBox.TextFormatter>
    30. <toolkit:PlainTextFormatter />
    31. </toolkit:RichTextBox.TextFormatter>
    32. </toolkit:RichTextBox>
    33. </local:RichTextBoxHelper>-->
    34. </DataTemplate>
    35. </DataGridTemplateColumn.CellTemplate>


    Code behind:

    VB.NET-Quellcode

    1. Public oc As New ObservableCollection(Of Pair)


    VB.NET-Quellcode

    1. Public Class Pair
    2. #Region "Properties"
    3. Private id As String
    4. Private source_segment As String
    5. Private target_segment As String
    6. #End Region
    7. Public Property URID() As String
    8. Get
    9. Return id
    10. End Get
    11. Set(ByVal value As String)
    12. id = value
    13. End Set
    14. End Property
    15. Public Property SOURCE() As String
    16. Get
    17. Return source_segment
    18. End Get
    19. Set(ByVal value As String)
    20. source_segment = value
    21. End Set
    22. End Property
    23. Public Property TARGET() As String
    24. Get
    25. Return target_segment
    26. End Get
    27. Set(ByVal value As String)
    28. target_segment = value
    29. End Set
    30. End Property
    31. End Class


    Befüllt über:

    VB.NET-Quellcode

    1. Dim PAAR As New Pair
    2. PAAR = New Pair
    3. PAAR.URID = str_id.ToString
    4. PAAR.SOURCE = str_source.ToString
    5. PAAR.TARGET = str_target.ToString
    6. oc.Add(PAAR)



    Bindung:

    VB.NET-Quellcode

    1. DG1.ItemsSource = oc.AsEnumerable


    AsEnumerable, deshalb weil ich später ein Paging einbauen möchte.

    Passt das so, oder kann/sollte man das noch optimieren?

    Get und Set für die RTBs hab ich noch nichts vorangebracht, aber bin noch dran.

    LG,
    Pascal

    *CodeTags korrigiert* ~NoFear23m
    :!: 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 „Nofear23m“ ()

    Hallo Pascal

    Das sieht ja schon mal gut aus. Das ist nun der WPF like Weg.

    Translating-IT schrieb:

    AsEnumerable, deshalb weil ich später ein Paging einbauen möchte

    Muss nicht sein. Die ObservableCollection erbt von Collection(Of T) und Collection(Of T) implementiert wiederum IEnumerable(Of T).
    Du kannst auch auf die ObservableCollection Take und Skip anwenden.

    VB.NET-Quellcode

    1. DG1.ItemSource = oc.Skip(10).Take(10)


    Translating-IT schrieb:

    Passt das so, oder kann/sollte man das noch optimieren?

    Nichts grawierendes. Du wirst es im Moment nicht benötigen aber wenn du später mal die Properties veränderst und möchtes das die Werte im View aktualisiert werden sollte INotifyPropertyChanged in die "Pair" Klasse implementiert werden und im Setter jedes Properties das Event OnPropertyChanged geworfen werden. Aber wenn es nicht benötigt wird ist es (noch) nicht nötig.

    Hier:

    VB.NET-Quellcode

    1. Dim PAAR As New Pair
    2. PAAR = New Pair
    3. PAAR.URID = str_id.ToString
    4. PAAR.SOURCE = str_source.ToString
    5. PAAR.TARGET = str_target.ToString
    6. oc.Add(PAAR)

    Brauchst du die Variable nicht zweimal instanziieren. PAAR = New Pair kann man weglassen denn das machst du ja mit Dim PAAR as [b]New[/b] Pair

    Das ganze könnte man mit einer überladung des Kostruktors verweinfachen oder wie folgt instanziieren:

    VB.NET-Quellcode

    1. oc.Add(New Pair() With {.URID = str_id.ToString, .SOURCE = str_source.ToString, .TARGET = str_target.ToString})



    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo Sascha,

    Quellcode

    1. Du kannst auch auf die ObservableCollection Take und Skip anwenden.


    Ah, ok. Gut zu wissen.

    Quellcode

    1. Du wirst es im Moment nicht benötigen aber wenn du später mal die Properties veränderst und möchtes das die Werte im View aktualisiert werden sollte INotifyPropertyChanged in die "Pair" Klasse implementiert werden und im Setter jedes Properties das Event OnPropertyChanged geworfen werden. Aber wenn es nicht benötigt wird ist es (noch) nicht nötig.

    Da in diesem Projekt nichts derartiges geplant ist, kann ich es weglassen. Das Einzige, was ich noch brauch ist die Formatierung der RTB-Texte beim ersten Befüllen. Und da brauch ich OnPropertyChanged nicht, oder? Danach wird nur noch per UI was geändert.

    Quellcode

    1. Brauchst du die Variable nicht zweimal instanziieren.


    Stimmt, habe ich übersehen.

    Quellcode

    1. Das ganze könnte man mit einer überladung des Kostruktors verweinfachen oder wie folgt instanziieren:


    Ist noch besser … 4 Zeilen Code weniger.

    Aber an dem depperten Get u. Set für die RTBs verzweifle ich.
    Ich check nicht mal, was ich, ausgehend vom XAML aus Post 21, "Implent"ieren muss um darauf zuzugreifen, ITextFormatter, oder was anderes? Mit was fange ich an?

    Quellcode

    1. Implements ITextFormatter
    2. Public Function GetText(ByVal document As FlowDocument) As String Implements ITextFormatter.GetText
    3. Dim tr As TextRange = New TextRange(document.ContentStart, document.ContentEnd)
    4. Using ms As MemoryStream = New MemoryStream()
    5. tr.Save(ms, DataFormats.Rtf)
    6. Return ASCIIEncoding.[Default].GetString(ms.ToArray())
    7. End Using
    8. End Function
    9. Public Sub SetText(ByVal document As FlowDocument, ByVal text As String) Implements ITextFormatter.SetText
    10. Try
    11. If String.IsNullOrEmpty(text) Then
    12. document.Blocks.Clear()
    13. Else
    14. Dim tr As TextRange = New TextRange(document.ContentStart, document.ContentEnd)
    15. Using ms As MemoryStream = New MemoryStream(Encoding.ASCII.GetBytes(text))
    16. tr.Load(ms, DataFormats.Rtf)
    17. End Using
    18. End If
    19. Catch
    20. Throw New InvalidDataException("Data provided is not in the correct RTF format.")
    21. End Try
    22. End Sub


    Ist das annähernd richtig, oder bin ich völlig auf dem Holzweg?

    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.
    Hallo Sascha @Nofear23m,

    Ich geb's auf. Ich krieg dieses sch… get und set für die RTBs einfach nicht hin.

    Kann ich die Texte beim Befüllen vom OC eigentlich irgendwie so "vorformatieren", dass die Texte gleich fett oder farbig in die RTBs geladen und entsprechend formatiert angezeigt werden? Dann bräuchte ich Get und Set hier nicht mehr.

    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.
    Hallo

    Sorry das ich nicht gleich Antworten kann/konnte, ich habe im Moment viel stress in der Arbeit. Ich wollte dir ein Beispiel erstellen, komme aber erst gegen Wochenende dazu.
    Ich weis was du meinst mit befüllen. Das geht natürlich auch, du kannst ja den zu übergebenen Text vorher quasi umformatieren, das ist aber ne doofe Arbeit und sicher mühseelig.

    Ich kann dir gerne (ich denke Freitag würde ich dazu kommen) ein kleines Beispiel machen, hier wäre Hilfreich ein paar Beispieltexte zu haben.
    Also ein paar Datensätze von deinen Rohdaten und jeweils das was am Ende rauskommen soll. Also den formatierten Part.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo Sascha,

    Kein Problem. Ist bei mir ja auch oft nicht anders.

    Ich hab mir die Beispiele zu Get und Set im Binding-Video angeschaut und auch so noch recherchiert, aber irgendwas scheine ich falsch zu machen. Das Get scheint nicht mal zu funktionieren.

    An sich sind die zu formatierenden Texte immer laut gleichem Schema. Über Get und Set würde ich es ja auch nur automatisiert umformatieren lassen. Meiner Meinung nach, macht es dann keinen Unterschied, ob ich es beim Get/Set per Formatierung der Paragraphen nach der Erstbefüllung mache, oder schon vorher. Ist nur einmal zu programmieren. Aber dass ich das Get/Set für die RTBs nicht hinbekomme, ärgert mich schon etwas.

    Die Ersetzungen habe ich vor der xceed-Version immer mit Regex-Match durchgeführt. Hat auch ganz gut geklappt.


    Da sich die Texte im Allgemeinen ändern und nur die zu formatierenden Teile gleich bleiben, ist ein Beispieltext recht einfach. Weitere Texte können nach Belieben generiert werden, indem weitere {t\d}- bzw. {s\d}-Platzhalter eingefügt bzw. generiert werden.


    Ausgangstext: {t1}Das ist ein Beispieltext{t2} mit unterschiedlicher Formatierung {s1}.

    Gewünschtes Format: {t1}Das ist ein Beispieltext{t2} mit unterschiedlicher Formatierung {s1}.


    {t\d} soll immer Fettschrift und violett sein, {s\d} immer Fettschrift und rot.

    Reicht das Beispiel oder brauchst Du mehr Text(e)?

    Ursprünglich wollte ich die {t\d} durch ein violettes Tag wie im nachfolgenden Beispiel ersetzen, aber das scheint laut meinen Recherchen in einer RTB noch schwieriger, wäre aber optisch etwas schöner, aber Violett und Fett passt auch ganz gut.

    Beispiel:

    oder halt ein rechteckiges oder wabenförmiges Tag.

    LG,
    Pascal
    Bilder
    • anni-tanni-tags-raw-doc.jpg

      53,04 kB, 655×294, 82 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.
    Hallo Pascal

    Ich habe mal ein kleine Beispiel erstellt da ich huete kurz Zeit hatte.

    Schau dir das mal an, ist evtl. nicht genau die Formattierung die du benötigst, aber anpassen ist ja einfach. Im Grunde ja nur eine spielerei.
    Ich habe die Formatierung nun so gestalltet das es immer auch einen CloseTag gibt. Also {ts} eröffnet den Tag und {\ts} schliesst diesen wieder. Aber wie gesagt, anpassen ist ja einfach.

    Ich denke damit solltest du nun dein Problem soweit lösen können denke ich.

    PS: Das zurückformatieren habe ich jetzt nicht vollständig implementiert, aber beim ersten Formatter habe ich dir zumindest ein Beispiel reingepackt wie es funktioniert.

    Grüße
    Sascha
    Bilder
    • Anmerkung 2019-07-13 154519.png

      23,31 kB, 709×440, 14 mal angesehen
    Dateien
    • WpfApp1.zip

      (1,51 MB, 4 mal heruntergeladen, zuletzt: )
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo Sascha,


    Danke, hab mir das Ganze mal angeschaut. Sehr interessantes Beispiel.

    Ich brauche im Endeffekt einen Kombination aus beiden Lösungsansätzen. Fettschrift für Rot und Tag für Violett. Aber das umzusetzen sollte in diesem Fall einfach sein, einfach das hernehmen, was ich jeweils benötige.

    Wie, über welche Zeile, kann ich das Tag verändern? Ich möchte versuchen, eine Wabe daraus zu machen.


    Ich habe auch versucht, die Daten in meine Lösung einzubinden, um dort mit der Datenstruktur und RTB-Einbindung weiterzuexperimentieren, die bei mir schon programmiert ist, aber ich erhalte 2 Fehlermeldungen:


    in der Haupt-XAML macht diese Zeile Probleme:

    Quellcode

    1. <rtbformatter:MySpecialFormatter/>



    Fehler:
    Der Name "MySpecialFormatter" ist im Namespace "clr-namespace:TMEdit.RtbFormatter" nicht vorhanden.

    Aber sie ist vorhanden.

    Eine Schnellaktion oder Refactoring wird nicht angeboten.

    Edit: obigen Fehler habe ich nun nach mehreren Versuchen durch eine erzwungene Neuerstellung der Projektmappe lösen können.


    In der Datei MySpecialIconFormatter

    schimpft VS, dass .Angle und .text jeweils kein Member von ucITs sind, aber sie sind doch in der entsprechenden XAML vorhanden.

    Auch hier wird wiederum weder Schnellaktion noch Refactoring angeboten.


    Grüße,
    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“ ()

    Neu

    Translating-IT schrieb:

    schimpft VS, dass .Angle und .text jeweils kein Member von ucITs sind, aber sie sind doch in der entsprechenden XAML vorhanden.

    Das ist der Grund warum ich immer Empfehle eigene Lösungen anhand der "Vorlage" zu implementieren. Mit Copy&Paste vergisst man schnell mal was. Dem UserControl habe ich nämlich genau diese Eigenschaften als DependencyProperties spendiert und im XAML dann schlicht darauf gebunden. Somit findet man diese nicht im XAML sondern in der CodeBehind. Bez. DependencyProperties verweise ich wiedermal auf meine Tutorialreihe.

    Wenn du eine Wabe daraus machen willst musst du nur das Usercontrol entsprechend verändern.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Neu

    na super … die einzige Datei, bei der ich komplett übersehen habe, die Codebehind anzuschauen … Bei allen anderen habe ich daran gedacht. *grml*

    Ich glaube es liegt daran, dass bei den anderen nichts im Codebehind war und deshalb hab ich da nimmer dran gedacht zu schauen.



    Dann werd ich mal weiter rumexperimentieren und schauen, ob noch was Problemchen bereitet. Aber ich glaube es sollte kein großes Problem sein.

    Auch den Get und Set nehme ich mir nochmal genauer unter die Lupe.

    Edit:

    Von den Formatierungen her schaut es schon ganz gut aus. Ich habe beide Formatter in einem Namespace kombiniert.

    Es gibt nur ein kleines Problem: die roten Texte in Fettschrift dienen dazu, dem Kunden zu zeigen, wo er was ändern kann/soll (also die rot formatierten Texte). Bei einigen Segmenten funktioniert das Ersetzen ohne Probleme, bei anderen wird folgende Fehlermeldung ausgeworfen:

    Nachricht = Das Objekt des Typs "System.Windows.Documents.InlineUIContainer" kann nicht in Typ "System.Windows.Documents.Run" umgewandelt werden.

    Bei diesem Test passiert es in jeder 2. "Tabellen"-Zeile. Kann auch nur ein Zufall sein, dass es in jeder 2. auftritt. Ich habe noch keine Zeit gehabt mir das genauer bzw. mit anderen Testdaten anzuschauen, da es schon recht spät ist, aber vielleicht fällt Dir ja auf Anhieb was dazu ein. Ein Verdacht von mir fällt darauf, dass es nur in Zellen auftritt, in denen beide Formatierungen (also tp und ts) vorhanden sind. Muss ich mir dann morgen oder so noch genauer anschauen.


    Die Änderung am UserControl habe ich noch nicht ganz raus, mir fehlen grad die Referenzpunkte zum Zeichnen. Erinnert mich irgendwie an PC Logo aus den 90ern. Gibt es nur die Möglichkeit die Linien programmatisch zu ziehen oder kann man die auch irgendwie "zeichnen"?

    Die Rückformatierung am Ende ist auch kein Problem in diesem Usecase. Ich rufe die Werte aus den Zellen im Codebehind über die OC ab und dort sind die Formatierungen nicht vorhanden. Nur die ursprünglichen Tags.

    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“ ()

    Neu

    Hallo,

    Der Fehler tritt in jedem Feld auf, das ein UserControl TP enthält. Unabhängig von dessen Position. Eigentlich sollte der Case Else den Text davor und danach in Run umwandeln (oder nicht?), aber das scheint nicht zu geschehen, und falls es doch geschieht, dann behält der InlineUIContainer die Kontrolle über das gesamte Feld.

    Grüße,
    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.

    Neu

    Translating-IT schrieb:

    wird folgende Fehlermeldung ausgeworfen

    Der InlineUIContainer ist wie der Name sagt wirklich nur da um UI, also Controls in eine RTB einzufügen. So wie ich es mit dem UserControl mache.
    Run ist nur Text, dafür benötigt es keinen InlineUIContainer. Schau dir mal auf MSDN die RTB genauer an und versuche zu lernen wie die RTB und deren Content aufgebaut werden muss/soll. Dann tust du dir gleich um einiges leichter.

    Translating-IT schrieb:

    Gibt es nur die Möglichkeit die Linien programmatisch zu ziehen oder kann man die auch irgendwie "zeichnen"?

    Sicher, es gibt Grafik-Programme welche direkt in XAML exportieren können. XAML ist ja Vektorbeasiert. Wenn du allerdings nicht mit den Path's arbeiten willst kannst du auch ein Image-Control verwenden.

    Ich kann dir bei deinem aktuellen problem nicht weiterhalfen ohne Code. Wenn du ein Problem mit einer Fehlermeldung hast ist es immer Hilfreich wenn du den relevanten Code postest, ich kann ja leider nicht wissen wie der aktuelle Stand ist und wo der Fehler auftritt. Wie gesagt musst du aber unbedingt versuchen zu verstehen was hier genau passiert und wie der Inhalt einer RTB aufgebaut ist. Nur so wirst du die Formatierung nach deinen wünschen anpassen können - und vor allem kann hier auch in sachen performance viel herausgeholt werden wenn man weis wie man die RTB aufbaut.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Neu

    Hallo Sascha,

    Sorry, hatte bewußt den Code noch nicht gepostet, da ich noch etwas rumexperimentiert habe. Leider habe ich aber keine zufriedenstellende Möglichkeit gefunden, beide Formatierungen in einem Namespace zu vereinen. Ich überlege aber, ob es nicht auch besser wäre trotzdem nur die Tags zu verwenden, auch wenn mir für den zu ändernden Text die Fettschrift lieber wäre. Je länger ich darüber nachdenke, hat beides (nur Tags bzw. eine Mischung) irgendwie Vor- und Nachteile.

    Hier mal mein Code soweit:

    VB.NET-Quellcode

    1. Namespace RtbFormatter
    2. Public Class MySpecialFormatter
    3. Implements ITextFormatter
    4. Public Sub SetText(document As FlowDocument, text As String) Implements ITextFormatter.SetText
    5. Dim textParts = text.Split("{"c,
    6. "}"c)
    7. Dim writeBold As Boolean = False
    8. Dim writeColor As Color = Colors.Black
    9. document.Blocks.Clear()
    10. Dim p As New Paragraph()
    11. document.Blocks.Add(p)
    12. For Each tp In textParts
    13. Select Case tp
    14. Case "tp"
    15. writeBold = True
    16. writeColor = Colors.Purple
    17. Dim uiBlock As New InlineUIContainer()
    18. Dim vb As New Viewbox() With {.Height = 25, .Width = 25, .VerticalAlignment = VerticalAlignment.Bottom}
    19. vb.Child = New uclTs() With {.Angle = 0, .Foreground = New SolidColorBrush(writeColor), .Text = "TP"}
    20. uiBlock.Child = vb
    21. p.Inlines.Add(uiBlock)
    22. Case "ts"
    23. writeBold = True
    24. writeColor = Colors.Red
    25. Case "\tp"
    26. writeBold = False
    27. writeColor = Colors.Black
    28. Dim uiBlock As New InlineUIContainer()
    29. Dim vb As New Viewbox() With {.Height = 25, .Width = 25, .VerticalAlignment = VerticalAlignment.Bottom}
    30. vb.Child = New uclTs() With {.Angle = 180, .Foreground = New SolidColorBrush(writeColor), .Text = "TP"}
    31. uiBlock.Child = vb
    32. p.Inlines.Add(uiBlock)
    33. writeColor = Colors.Black
    34. Case "\ts"
    35. writeBold = False
    36. writeColor = Colors.Black
    37. Case Else
    38. Dim r As New Run(tp)
    39. r.FontWeight = If(writeBold, FontWeight.FromOpenTypeWeight(800), FontWeight.FromOpenTypeWeight(500))
    40. r.Foreground = New SolidColorBrush(writeColor)
    41. p.Inlines.Add(r)
    42. End Sub
    43. Public Function GetText(document As FlowDocument) As String Implements ITextFormatter.GetText
    44. Dim doc = document
    45. Dim text As String = ""
    46. For Each b As Paragraph In doc.Blocks.ToList
    47. For Each inline As Run In b.Inlines.ToList
    48. text += inline.Text
    49. Next
    50. Next
    51. Return text
    52. End Function
    53. End Class
    54. End Namespace


    Wenn ich die Funktion GetText leer lasse, habe ich keine Fettformatierungen, dafür ist der Text aber auch mit Tags veränderbar, wenn ich den Code für die Formatierungen einbinde, kann ich die Felder mit Tags nicht verändern.


    Ich es eigentlich auch möglich die Violetten Tags als nicht löschbar/veränderbar zu deklarieren? Für so etwas könnte ich später eventuell Verwendung haben, habe aber bei meinen Google-Suchen nichts entsprechendes gefunden.


    In der Zwischenzeit habe ich auch die Paginierung mit Deinem Tipp hinbekommen. Geht ja viel einfacher, als alle immer in diversen Foren schimpfen.

    Hier gibt es aber noch ein kleineres Problem mit den Tags. Wenn ich die Seiten wechsle ohne was zu ändern gibt es kein Problem. Die Tags bleiben. Wenn aber in einer Textbox irgendwas verändert wird (auch außerhalb der Tags oder Formatierungen), man dann eine andere Seite der Ergebnisse aufruft und wieder zu der Seite mit der Änderung zurückkehrt, sind die Tags/Formatierungen verschwunden.

    Das ergibt in meinen Augen keinen Sinn, da am Tag selbst nichts geändert wurde. Ich gehe mal davon aus, dass ich die Formatierungen/Tags wieder laden kann, indem ich den MySpecialFormatter nochmal drüberlaufen lasse, wenn eine Seite neu geladen wird, aber wie gesagt, ergibt es für mich keinen Sinn, dass die Formatierungen/Tags überhaupt verschwinden.

    Das möchte ich mir aber noch gerne selbst etwas anschauen.


    Zu den Fettformatierungen habe ich noch eine Frage: Ist es in irgendeinem Dir bekannten Szenario möglich, dass durch Ändern des Texts zwischen den Auslösern (edit: die Auslöser sieht man ja in der RTB nicht) die Auslöser {ts} und {/ts} teilweise gelöscht und somit "beschädigt" würden. Wenn ein Start- oder Endauslöser gelöscht würde, wäre das kein Problem, nur wäre es blöd, wenn zum Beispiel nur {t, {ts, ts} oder eine ähnliche Kombination stehen bleiben würde. Ich glaube zwar nicht, dass es passieren kann, aber ich möchte es nur mit Sicherheit ausschließen können.

    Grüße,
    Pascal

    *CodeTags editiert* ~NoFear23m
    :!: 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 „Nofear23m“ ()

    Neu

    Hallo nochmal

    Translating-IT schrieb:

    Leider habe ich aber keine zufriedenstellende Möglichkeit gefunden, beide Formatierungen in einem Namespace zu vereinen.

    Wenn beide Klassen im Namespace RtbFormatter sind, sind dies auch im XAML im selben Namespace. Oder meinst du was anderes?

    Translating-IT schrieb:

    Ich überlege aber, ob es nicht auch besser wäre trotzdem nur die Tags zu verwenden

    Die entscheidung kann ich dir nicht abnehmen, das musst du wissen wie du es willst.

    Translating-IT schrieb:

    Wenn ich die Funktion GetText leer lasse, habe ich keine Fettformatierungen, dafür ist der Text aber auch mit Tags veränderbar, wenn ich den Code für die Formatierungen einbinde, kann ich die Felder mit Tags nicht verändern.

    Wie nicht verändern. Bei meinem Beispielprojekt ist es änderbar. Was du noch implementieren musst ist das in GetText (also beim zurückschreiben) die "Tags" wieder mit übernommen werden. wie ich geschrieben habe, habe ich dies nicht implementiert da ich dir auch noch was zum lernen übrig lassen wollte.

    Translating-IT schrieb:

    Ich es eigentlich auch möglich die Violetten Tags als nicht löschbar/veränderbar zu deklarieren?

    Wäre sicher machbar. hierfür müsstest du aber um einiges mehr Logik implementieren. Auf das gehe ich aber am schluss dieser Antwort noch ein.

    Translating-IT schrieb:

    Die Tags bleiben. Wenn aber in einer Textbox irgendwas verändert wird (auch außerhalb der Tags oder Formatierungen), man dann eine andere Seite der Ergebnisse aufruft und wieder zu der Seite mit der Änderung zurückkehrt, sind die Tags/Formatierungen verschwunden.

    Das hat wieder genau damit zu tun. In der GetText Methode wird der Text wieder zurückgespeichert. Wenn beim zurückspeichern die "Tags" nicht wieder mit hineingeschrieben werden kann bei neuerlichem durchlaufen von SetText nichts passieren. wie auch, es sind in dem Moment keine Tags mehr da.

    Translating-IT schrieb:

    Wenn ein Start- oder Endauslöser gelöscht würde, wäre das kein Problem, nur wäre es blöd, wenn zum Beispiel nur {t, {ts, ts} oder eine ähnliche Kombination stehen bleiben

    Auch das muss in deine Logik mit hinein. Ist eine reine Spielerei.


    Im Grunde ist es so das du in der SetText Methode den Text analysierst und entsprechend dann in der RTB renderst. Hier ist der Fantasie keine Grenzen gesetzt. DU bist Herr der Lage und kannst entscheiden welche Textteile am ende wie aussehen sollen.
    In GetText musst du andersrum vorgehen und die Struktur der RTB analysieren. Für jedes Element (Paragraph, UIContainer usw.) musst du nun wieder das passende "Tag" (ich würde es fast Platzhalter nennen) wieder im Text einfügen. Klar, wenn nicht, kann der Text nie wieder ein zweites mal korrekt in der RTB gerendert werden da keine Tag mehr vorhanden sind.

    DU kümmerst dich also um beide Wege. DU musst die Logik implementieren. Ist eine spielerei, aber dafür sehr flexibel. Einfach Haltepunkte setzen und den Code durchgehen.

    Grüße
    Sascha

    PS: Bitte verwende die richtigen CodeTags - Danke
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Neu

    Hallo Sascha,

    Wenn beide Klassen im Namespace RtbFormatter sind, sind dies auch im XAML im selben Namespace.


    Das ist mir schon klar. Was ich meinte, ist mein bisheriger Code. Ich schaffe es nicht beide Varianten so in den Code einzubinden, dass beides funktioniert. Mit der jetzigen Variante habe ich zwar Platzhalter und Fettschrift wie gewünscht, der Benutzer kann aber in RTBs mit Platzhaltern den Text nicht verändern, weil es eine Fehlermeldung rausknallt (siehe weiter oben).
    Wenn ich den GetText leer lasse, funktionieren zwar sowohl Formatierungen, Platzhalter als auch das Ändern der Texte, aber natürlich befüllt es am Ende die RTBs nicht mehr, wenn schon was geändert und die Seite gewechselt und wieder zurückgewechselt wurde, und lässt sie leer. Was ja auch Sinn macht. Ich verstehe nur nicht, warum die beiden nicht kombinierbar zu sein scheinen.

    Wie nicht verändern. Bei meinem Beispielprojekt ist es änderbar.


    Ja, im Beispiel funktioniert es problemlos, wenn ich mich in meinem Projekt jeweils für einen Namespace entscheide, funktioniert es auch, aber ich versuche ja gerade eine Kombination aus beiden Namespaces zu erstellen. Da funktioniert es komischerweise nicht mehr. (Siehe Code weiter oben).

    Ich habe zumindest schon mal rausgefunden, dass der GetText-Teil das Problem zu verursachen scheint und nicht wie ursprünglich vermutet im SetText. Die Frage ist noch wo.
    Hm. *lol* bei 8 Zeilen … an sich in der 4. Zeile, da Runs aufgerufen werden, aber InlineUIContainer dazwischen sind. Muss ich den Schmarrn auf InlineUIContainer und Runs aufteilen? Geht das überhaupt?

    Auch das muss in deine Logik mit hinein.

    Das heißt es kann also passieren, dass ein Tag zum Teil gelöscht oder beschädigt wird, wenn der Benutzer ewas am Fett formatierten Text ändert. Habe ich das richtig verstanden?

    Edit: Wie ich die Formatierungen über GetText wieder reinbekomme, habe ich rausgefunden, nur erkenne ich nicht, wo ich diese setzen muss. Bei einer Web-App würde ich mir leichter tun, da ich von der angezeigten Seite, den Quelltext anzeigen lassen kann, und nach gewissen Elementen Ausschau halten kann. Hier geht das aber nicht.

    Hinterlässt die erste Umwandlung irgendwelche Spuren (Tags o. ä.), woran ich erkennen kann, welcher Teil formatiert war? Dann könnte ich danach suchen und einfach die Tags rundherum setzen bzw. ersetzen.
    Oder muss ich die gleiche Suchlogik, wie beim Erstellen der ursprünglichen Tags auch im GetText-Bereich nochmal durchlaufen lassen. Wenn ich also vorher "es" (oder einen RegEx) gesucht habe, auch im GetText wider nach genau diesem Wort oder RegEx suchen?

    Grüße,
    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“ ()