Mauscursor für Textblock ändern

  • WPF MVVM
  • .NET (FX) 4.5–4.8

Es gibt 37 Antworten in diesem Thema. Der letzte Beitrag () ist von Amro.

    Mauscursor für Textblock ändern

    Guten Morgen :)

    ich möchte, wenn man mit der Maus über meinen Textblock fährt, den Mauscursor in eine Hand ändern. Mein XAML sieht so aus:

    XML-Quellcode

    1. ​<Border Grid.Column="1" Grid.Row="2" BorderThickness="0">
    2. <Border.InputBindings>
    3. <MouseBinding MouseAction="LeftClick" Command="{Binding MailAnMich}"/>
    4. </Border.InputBindings>
    5. <TextBlock Style="{StaticResource HyperLink}" Text="xxx@yyy.de" TextDecorations="Underline" FontWeight="Bold" Foreground="{DynamicResource VordergrundfarbeBrush}" VerticalAlignment="Center" HorizontalAlignment="Left" ToolTip="Öffne dein Standard-Mailprogramm und schreibe dem Entwickler eine E-Mail..."/>
    6. </Border>


    Und in der Application.xaml hab ich Folgendes:

    <S

    XML-Quellcode

    1. tyle TargetType="{x:Type TextBlock}" x:Key="HyperLink">
    2. <Style.Triggers>
    3. <Trigger Property="IsMouseOver" Value="True">
    4. <Setter Property="Cursor" Value="Hand"/>
    5. </Trigger>
    6. </Style.Triggers>
    7. </Style>


    Passiert aber leider nichts, auch nicht wenn ich die Styledefinition nicht benutze, sondern direkt im TextBlock die Property Cursor="Hand" setze...

    Weiss jemand, was ich falsch mache?
    Soweit ich weiß musst du dafür ein DataTrigger verwenden.

    Hier mal ein Beispiel:

    XML-Quellcode

    1. <Button x:Name="NextButton"
    2. Content="Go"
    3. Command="{Binding GoCommand }">
    4. <Button.Style>
    5. <Style TargetType="{x:Type Button}">
    6. <Setter Property="Cursor" Value="Arrow"/>
    7. <Style.Triggers>
    8. <DataTrigger Binding="{Binding Path=IsWorking}" Value="True">
    9. <Setter Property="Cursor" Value="Wait"/>
    10. </DataTrigger>
    11. </Style.Triggers>
    12. </Style>
    13. </Button.Style>
    14. </Button>
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.
    Wüsste nicht was. Hab sogar probiert nen StackPanel nochmal drumzumachen...

    Das hier von MS Docs:

    XML-Quellcode

    1. <StackPanel
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. >
    5. <StackPanel Name="CursorForced" ForceCursor="true" Cursor="Hand">
    6. <Label>Cursors Forced</Label>
    7. <TextBox>Fill me in!</TextBox>
    8. </StackPanel>
    9. <StackPanel Name="CursorNotForced">
    10. <Label>Cursors Not Forced</Label>
    11. <TextBox>Fill me in!</TextBox>
    12. </StackPanel>
    13. </StackPanel>


    und meins:

    XML-Quellcode

    1. ​<Border BorderThickness="0" Grid.Column="1" Grid.Row="2" ForceCursor="True" Cursor="Hand">
    2. <Border.InputBindings>
    3. <MouseBinding MouseAction="LeftClick" Command="{Binding MailAnMich}"/>
    4. </Border.InputBindings>
    5. <TextBlock Text="xxx@yyy.de" TextDecorations="Underline" FontWeight="Bold" Foreground="{DynamicResource VordergrundfarbeBrush}" VerticalAlignment="Center" HorizontalAlignment="Left" ToolTip="Öffne dein Standard-Mailprogramm und schreibe dem Entwickler eine E-Mail..."/>
    6. </Border>
    Vollzitat des direkten Vorposts an dieser Stelle entfernt ~VaporiZed

    Ja wirklich... Geht net....

    Obwohl ich beides (Post1 und 3) so auf stackoverflow.com gesehen hab...

    Manchmal wünsch ich mir dass XAML ein bisschen intuitiver wäre...

    @ErfinderDesRades
    @siycah

    Edit:

    Hab den Code jetzt mal in ein komplett unkomplexes View (eine Custom-MessageBox) reingemacht und siehe da, es funktioniert.
    Keine Ahnung warum das in anderen UserControls net funzt :(

    Ich schau mal dass ich eins von den "grossen" UserControls mal hier poste aber jetzt muss ich erstmal die gravierenderen Sachen debuggen... :)

    @ErfinderDesRades
    @siycah
    Edit2:

    Hier mal ein UserControl, bei dem es nicht funktioniert (Zeile 34 und Zeile 50):

    Spoiler anzeigen

    XML-Quellcode

    1. <UserControl x:Class="LicensingView"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    6. xmlns:local="clr-namespace:VamosALaPlayer_3._0.View"
    7. mc:Ignorable="d"
    8. d:DesignHeight="1000" d:DesignWidth="500">
    9. <Grid>
    10. <Grid.RowDefinitions>
    11. <RowDefinition Height="70"/>
    12. <RowDefinition Height="50"/>
    13. <RowDefinition Height="90"/>
    14. <RowDefinition Height="200"/>
    15. <RowDefinition Height="70"/>
    16. <RowDefinition Height="70"/>
    17. </Grid.RowDefinitions>
    18. <TextBlock Grid.Row="0" Margin="30, 30, 30, 0" Background="Transparent" Foreground="{DynamicResource VordergrundfarbeBrush}" FontWeight="Bold" TextWrapping="Wrap" Text="Wähle diese App oder ein Paket aus, um dessen Lizenzierungsinformationen anzuzeigen:" TextAlignment="Justify"/>
    19. <ComboBox ItemsSource="{Binding Pakete}" DisplayMemberPath="Paket" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="30, 0, 30, 0" ToolTip="Wähle hier diese App oder ein Paket aus, um dessen Lizenzierungsinformationen anzuzeigen..." IsEditable="False" SelectedItem="{Binding Paket, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"/>
    20. <Grid Grid.Row="2" Margin="30, 0, 30, 0">
    21. <Grid.ColumnDefinitions>
    22. <ColumnDefinition Width="50*"/>
    23. <ColumnDefinition Width="50*"/>
    24. </Grid.ColumnDefinitions>
    25. <StackPanel Orientation="Vertical" Grid.Column="0">
    26. <Label Content="Art der Lizenz:" Foreground="{DynamicResource VordergrundfarbeBrush}"/>
    27. <Label Content="Copyright-Inhaber:" Foreground="{DynamicResource VordergrundfarbeBrush}"/>
    28. <Label Content="Website:" Foreground="{DynamicResource VordergrundfarbeBrush}"/>
    29. </StackPanel>
    30. <StackPanel Orientation="Vertical" Grid.Column="1">
    31. <Label Content="{Binding LizenzArt, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Foreground="{DynamicResource VordergrundfarbeBrush}"/>
    32. <Label Content="{Binding CopyRight, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Foreground="{DynamicResource VordergrundfarbeBrush}"/>
    33. <Border BorderThickness="0" ForceCursor="True" Cursor="Hand"> <!--hier-->
    34. <Border.InputBindings>
    35. <MouseBinding MouseAction="LeftClick" Command="{Binding OeffneWebSite}"/>
    36. </Border.InputBindings>
    37. <TextBlock VerticalAlignment="Bottom" Margin="4, 0, 0, 0" Text="{Binding WebSite, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Foreground="{DynamicResource VordergrundfarbeBrush}" FontWeight="Bold" TextDecorations="Underline" TextTrimming="CharacterEllipsis"/>
    38. </Border>
    39. </StackPanel>
    40. </Grid>
    41. <ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Row="3" Margin="30, 0, 30, 0">
    42. <Border Background="Transparent" BorderBrush="{DynamicResource VordergrundfarbeBrush}" BorderThickness="1">
    43. <TextBlock Background="Transparent" Foreground="{DynamicResource VordergrundfarbeBrush}" TextWrapping="Wrap" Text="{Binding Paket.LizenzierungsVereinbarungen, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" TextAlignment="Justify"/>
    44. </Border>
    45. </ScrollViewer>
    46. <StackPanel Margin="30, 0, 30, 0" Orientation="Horizontal" Grid.Row="4" HorizontalAlignment="Center">
    47. <TextBlock Text="Noch Fragen? Kontaktiere den Entwickler: " TextAlignment="Left" Foreground="{DynamicResource VordergrundfarbeBrush}" VerticalAlignment="Center"/>
    48. <Border BorderThickness="0" ForceCursor="True" Cursor="Hand"> <!--hier-->
    49. <Border.InputBindings>
    50. <MouseBinding MouseAction="LeftClick" Command="{Binding MailAnMich}"/>
    51. </Border.InputBindings>
    52. <TextBlock Foreground="{DynamicResource VordergrundfarbeBrush}" TextAlignment="Right" VerticalAlignment="Center">
    53. <Underline><Bold>xxx@yyy.de</Bold></Underline>
    54. </TextBlock>
    55. </Border>
    56. </StackPanel>
    57. <Button Content="Schliessen" Grid.Row="5" Margin="30, 0, 30, 30" BorderBrush="{DynamicResource VordergrundfarbeBrush}" BorderThickness="1" Command="{Binding Schliessen}"/>
    58. </Grid>
    59. </UserControl>


    und hier funktioniert es (Zeile 22):
    Spoiler anzeigen

    XML-Quellcode

    1. <UserControl x:Class="OKDialogView"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    6. xmlns:local="clr-namespace:VamosALaPlayer_3._0.View"
    7. xmlns:viewmodel="clr-namespace:VamosALaPlayer_3._0.ViewModel;assembly=VamosALaPlayer_3._0.ViewModel"
    8. mc:Ignorable="d"
    9. d:DesignHeight="450" d:DesignWidth="800">
    10. <Grid>
    11. <Grid>
    12. <Grid.RowDefinitions>
    13. <RowDefinition Height="50*"/>
    14. <RowDefinition Height="40*"/>
    15. <RowDefinition Height="5*"/>
    16. <RowDefinition Height="15"/>
    17. </Grid.RowDefinitions>
    18. <TextBlock Grid.Row="0" Margin="30" Background="Transparent" Foreground="{DynamicResource VordergrundfarbeBrush}" TextWrapping="Wrap" Text="{Binding Meldung}" TextAlignment="Justify"/>
    19. <Button Content="OK" Grid.Row="1" Margin="30" BorderBrush="{DynamicResource VordergrundfarbeBrush}" BorderThickness="1" Command="{Binding OK}"/>
    20. <StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Center" Visibility="{Binding KontaktSichtBar, Mode=OneWay}" VerticalAlignment="Top">
    21. <TextBlock Text="Probleme? Bitte kontaktiere den Entwickler: " Foreground="{DynamicResource VordergrundfarbeBrush}"/>
    22. <Border BorderThickness="0" ForceCursor="True" Cursor="Hand">
    23. <Border.InputBindings>
    24. <MouseBinding MouseAction="LeftClick" Command="{Binding MailAnMich}"/>
    25. </Border.InputBindings>
    26. <TextBlock Text="xxx@yyy.de" Foreground="{DynamicResource VordergrundfarbeBrush}" FontWeight="Bold" TextDecorations="Underline"/>
    27. </Border>
    28. </StackPanel>
    29. </Grid>
    30. </Grid>
    31. </UserControl>

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „VaporiZed“ ()

    Wenn ich aus Deinem scheinbar nicht funktionierendem UserControl vom Vorpost alle Komponenten entferne, die aufgrund fehlender Ressourcen mir nicht zur Verfügung stehen, bekomme ich nen HyperlinkHand-Cursor bei den gewünschten Stellen. So what?
    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

    Erstmal danke dass du dir die Mühe gemacht hast, das auseinander zu klamüseln. Das ist echt interessant. Ich bin davon ausgegangen, dass Properties, die direkt im XAML des Controls festgelegt werden, alles andere was ich in den Resources als Style festgelegt hab, overriden.

    Oder bin ich da falsch informiert?
    Ja, durchaus möglich, ich arbeite (noch lange) nicht mit der WPF. Aber ok, wenn ich Deinen Code unverändert übernehme und für den oberen TextBlock einen FallBackValue einbaue, damit ich aufgrund der fehlenden Referenzen überhaupt was angezeigt bekomme, das gleiche Resultat: die gewünschte Hand.
    Bilder
    • B1.jpg

      18,18 kB, 500×500, 87 mal angesehen
    • B2.jpg

      21,23 kB, 500×500, 84 mal angesehen
    • B3.jpg

      19,9 kB, 500×500, 76 mal angesehen
    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.
    Okay das ist ja echt hart.

    Ich benutze in meinem ViewModel das hier:

    Mouse.OverrideCursor = System.Windows. Input.Cursors.Arrow

    Oder so ähnlich.

    Gut möglich, dass das in der Hierarchie höhere Priorität hat wie das XAML.

    Dabei muss ich betonen, dass der Code im VM in keinerlei Beziehung zu meinen Textblöcken ist, sondern nur wenn mein ViewModel länger braucht bei irgendeiner Aktion setze ich so den Cursor programmweit.

    Wenn gar nichts hilft, dann probier ich es mal mit Code Behind, bevor ich da jetzt ewig in meinen VMs rumwurschtel...
    Was mir jetzt grad auffällt, ist Post#2

    kafffee schrieb:

    Das hier geht auch nicht:
    Das kann ich schon (fast) nicht nachvollziehen.
    Denn das hier klappt wunderbar bei mir:

    XML-Quellcode

    1. <UserControl x:Class="LicensingView"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    6. mc:Ignorable="d"
    7. d:DesignHeight="200" d:DesignWidth="200">
    8. <StackPanel>
    9. <TextBlock Text="Hallo!" ForceCursor="True" Cursor="Hand" />
    10. </StackPanel>
    11. </UserControl>


    ##########

    kafffee schrieb:

    Ich benutze in meinem ViewModel das hier:

    Eh, ja gut. Das dürfte alle anderen XAML-Versuche zunichte machen.
    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.

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

    Jou, hab ich gelesen.
    Hatte grad noch meinen Post ergänzt, Deine OverrideCursor-Zeile macht nach ersten Tests alle XAML-Einstellungen zunichte.
    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.

    kafffee schrieb:

    Ich benutze in meinem ViewModel das hier:

    Mouse.OverrideCursor = System.Windows. Input.Cursors.Arrow


    Also mit meinen Anfänger Kentnissen in der WPF, würde ich sagen das der Cursors im ViewModel auch nix zu suchen hat.
    Ich war der Meinung das System.Windows nur in der UI benutzt werden darf. ?(

    Edit: Ok wenn du dein ViewModel nur für WPF bauen willst dann kann man das evt. so machen.
    Das ist Grund warum man ViewModels in einem eignen Projekt auslagern sollte, dann kann sowas nicht passieren.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Amro“ ()

    Okay super jetzt funktionierts auch nicht in meinen Dialogen. Gestern gings noch :(

    Weiss jemand auf die Schnelle ne Alternative zu Mouse.OverrideCursor, die eben nicht auf Dauer overrridet. Hab bis jetzt über Google nichts gefunden...

    Edit: @Amro
    Was meinst du mit VM nur für WPF?

    Hast du ne bessere Idee?

    Bin offen für neue Ideen :)

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „kafffee“ ()

    kafffee schrieb:

    Hast du ne bessere Idee?

    Nein :P
    Aber ich finde das ist eine schöne Aufgabe die wir gemeinsam als kleines Projekt angehen könnten.
    Kann ich auch gebrauchen in meinen kleinen Projekten
    Stichwort IsBusy.
    In Maui ist das eingebaut.
    Vielleicht sollten wir es erstnmal mit Converter versuchen.
    Später versuchen das wie in Net Maui umsetzten.
    Also ein eignes UserControl das auf den Bool IsBusy reagiert.
    Bin gespannt ob wir das hin bekommen?
    Lade das Projekt sobald ich ein Grundgerüst hab hoch.

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

    So das ist nur ein Grundgerüst.
    Mein Gedanke :
    Ein Converter gehört immer und ist immer nur für die View.
    Erstellt man jetzt zum Beispiel eine Android App, muss man nur den Converter in dessen View anpassen.
    Wobei Maui jetzt ein schlechtes Beispiel ist da es das von Hausaus mitbringt.

    Hier könnte man jetzt auf die System.Windows zugreifen ohne das MVVM zu verletzten.
    In ViewModel muss man jetzt nur die Eigenschaft ISBusy ändern.
    Alle ViewModels hätten diese Eigenschaft das Sie von ViewModelBase erben.
    Ich glaub darauf können wir aufbauen wenn interesse besteht.
    Bin gespannt auf eure Meinung und Ideen für den Ausbau.
    Ich glaub es lohnt sich wirklich hier weiter zu machen und ein cooles featcher zu entwicklen.
    Ihr hab bestimmt mehr erfahrung mit der Programmierung und könnt mir
    gerade vielleicht bei Async und RelayCommand noch was beibringen.

    Achtung den RelayCommand hab ich auch nur kopiert :)

    Edit:
    Das ist für lange Processe und für den MouseIsOver hast du ja den Cursor="Hand" in XAML

    kafffee schrieb:

    Was meinst du mit VM nur für WPF?

    Wegen dein Cursor im ViewModel. System.Windows gibt es nur in WPF.
    Du kannst das ViewModel nicht in eine Android App oder WinUI oder so verwenden.
    Ich glaub selbst in WinForms nicht...


    Dateien
    • IsBusyTest.zip

      (48,32 kB, 321 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 12 mal editiert, zuletzt von „Amro“ ()

    @Amro

    Ich muss gestehen ich versteh nicht ganz worauf du raus willst.

    Was ich sagen kann ich benutze das MultiProject Template von Nofear23m da erben die ViewModels von ViewModel Base und haben eine Property VMIsBusy.


    Ansonsten keine Ahnung von Maui aber stell mal deine Fragen zu RelayCommands vllt kann ich dir da ja helfen :)

    Edit @Amro
    So jetzt hats auch bei mir geschnaggelt, du willst mit nem Konverter dass Boolean IsBusy in einen Mauszeigertyp umwandeln oder?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kafffee“ ()