RequestNavigate über Code behind hinzufügen

  • WPF

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    RequestNavigate über Code behind hinzufügen

    Hallo,

    ich habe einen Textblock in meiner XAML und versuche über Code behind mehrere Hyperlinks einzufügen. An sich kein Problem bis auf RequestNavigate. Das bekomme ich einfach nicht eingebaut. Alles was ich online dazu finde ist zu C# und sobald ich das versuche, bekomme ich einen Fehler angezeigt.

    Es geht darum, dass ich eine Liste mit einer unbestimmten Zahl unbekannter Links auslese und diese im Textblock anzeigen möchte, sodass sie anklickbar sind. Das anklickbar scheitert daran, dass ich es nicht schaffe RequestNavigate anzuhängen. Wenn ich einen Testlink direkt in XAML erstelle, klappt alles wunderbar, nur bringt das für die Liveversion nichts, da die Links nicht bekannt sind.


    Bis jetzt habe ich diesen Teil erfolgreich umgesetzt:

    VB.NET-Quellcode

    1. Dim uri As New Uri(fi.FullName)
    2. Dim h As New Hyperlink With {
    3. .NavigateUri = New Uri(fi.FullName)
    4. }
    5. Tblock1.Inlines.Add(New LineBreak)
    6. h.Inlines.Add(fi.Name)
    7. Tblock1.Inlines.Add(h)



    XAML:

    XML-Quellcode

    1. <TextBlock x:Name="Tblock1" TextWrapping="Wrap" Margin="758,0,0,0" Height="Auto" Width="Auto"><Run Text="Treffer:" FontWeight="Bold" FontSize="13"/></TextBlock>


    wo und wie muss ich jetzt RequestNavigate einbauen?


    EDIT: *grml* Warum habe ich das erst jetzt gefunden?!

    Anbei die Lösung (AddHandler):

    VB.NET-Quellcode

    1. Dim uri As New Uri(fi.FullName)
    2. Dim h As New Hyperlink With {
    3. .NavigateUri = New Uri(fi.FullName)
    4. }
    5. AddHandler h.RequestNavigate, AddressOf Hyperlink_RequestNavigate
    6. Tblock1.Inlines.Add(New LineBreak)
    7. h.Inlines.Add(fi.Name)
    8. Tblock1.Inlines.Add(h)



    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 2 mal editiert, zuletzt von „Translating-IT“ ()

    Tatsächlich habe ich mich mit Hyperlinks so noch gar nicht auseinander gesetzt. Aber interessant, wie man das einfach umsetzen kann.

    Ich habe in meinem Programm einfach ein MouseDown-Event genommen und darauf reagiert und dem Text-Feld einfach eine entsprechende Formatierung gegeben.

    Aber deine Lösung werde ich mir demnächst dankend ansehen ^^
    Hallo Leute

    Warum das Leben so schwer machen?
    Es gibt ja ein "Control" (OK, Control ist es nicht wirklich, es ist ein FlowContent-Element, kann aber innerhalb eines Controls gerendert werden) welches genau wie ein Hyperlink aussieht ohne zutun des Designers.

    XML-Quellcode

    1. <TextBlock>
    2. <Hyperlink NavigateUri="http://www.google.com" RequestNavigate="Hyperlink_RequestNavigate">
    3. Hier klicken
    4. </Hyperlink>
    5. </TextBlock>


    Und der Handler sieht dann wie folgt aus:

    VB.NET-Quellcode

    1. Private Sub Hyperlink_RequestNavigate(sender As Object, e As RequestNavigateEventArgs)
    2. 'for .NET Core you need to add UseShellExecute = true
    3. 'see https://docs.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.useshellexecute#property-value
    4. Process.Start(New ProcessStartInfo(e.Uri.AbsoluteUri))
    5. e.Handled = True
    6. End Sub


    Hat man mehrere Hyperlinks im Einsatz bietet es sich an sich ein AttachedProperty zu erstellen welches einem den Handler abnimmt und somit auch MVVM Konform wäre:

    VB.NET-Quellcode

    1. Namespace Extensions
    2. Public Class HyperlinkExtension
    3. Inherits DependencyObject
    4. Public Shared Function GetIsExternal(ByVal obj As DependencyObject) As Boolean
    5. Return CBool(obj.GetValue(IsExternalProperty))
    6. End Function
    7. Public Shared Sub SetIsExternal(ByVal obj As DependencyObject, ByVal value As Boolean)
    8. obj.SetValue(IsExternalProperty, value)
    9. End Sub
    10. Public Shared ReadOnly IsExternalProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsExternal", GetType(Boolean), GetType(HyperlinkExtension), New UIPropertyMetadata(False, AddressOf OnIsExternalChanged))
    11. Private Shared Sub OnIsExternalChanged(ByVal sender As Object, ByVal args As DependencyPropertyChangedEventArgs)
    12. Dim hyperlink = TryCast(sender, Hyperlink)
    13. If CBool(args.NewValue) Then
    14. AddHandler hyperlink.RequestNavigate, AddressOf Hyperlink_RequestNavigate
    15. Else
    16. RemoveHandler hyperlink.RequestNavigate, AddressOf Hyperlink_RequestNavigate
    17. End If
    18. End Sub
    19. Private Shared Sub Hyperlink_RequestNavigate(ByVal sender As Object, ByVal e As System.Windows.Navigation.RequestNavigateEventArgs)
    20. Dim p As Process = New Process()
    21. p.StartInfo = New ProcessStartInfo(e.Uri.AbsoluteUri)
    22. p.StartInfo.UseShellExecute = True
    23. p.Start()
    24. e.Handled = True
    25. End Sub
    26. End Class
    27. End Namespace


    Anwendung dann ganz simple mit:

    XML-Quellcode

    1. <TextBlock>
    2. xmlns:ext="clr-namespace:WpfApp1.Extensions"
    3. ....
    4. <Hyperlink NavigateUri="http://www.google.com" ext:HyperlinkExtension.IsExternal="True">
    5. Hier klicken
    6. </Hyperlink>
    7. </TextBlock>

    so geht nun der Link automatisch auf wenn ​IsExternal den Wert ​true ausweist.

    Da die Eigenschaft als DependencyProperty implementiert ist kann auch darauf gebunden werden, so kann auch von einem ViewModel aus gesteuert werden welchen Wert ​IsExternal hat.
    Sauber und immer wieder anwendbar.
    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. ##

    Ja, wie gesagt, ich bin erst seit knapp über einem Jahr dabei und habe mich bisher noch nicht so damit befasst. Aber seitdem ich hier häufiger und stringenter Aktiv bin, schnappe ich immer mehr auf, was nützlich oder genial ist und an das ich dann später - sollte ich in der Situation bin - wieder zurückdenke und mich entsinne, hier nochmals nachzulesen :)
    Diese Beispiele helfen mir ungemein, mein Wissen zu erweitern.

    PadreSperanza schrieb:

    Ja, wie gesagt, ich bin erst seit knapp über einem Jahr dabei

    Sollte ja auch keinerlei Kritik sein, sollte dir eben nur zeigen das es eben auch einen Weg gibt bei dem du keinen CodeBehind benötigst und somit die Funktionalität "eingebaut" ist, was ich immer viel angenehmer finde.

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