WPF - Button Background verschwindet bei Hover

  • WPF

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    WPF - Button Background verschwindet bei Hover

    Hi,

    vorab... Ich habe in Google x Samples gefunden die das Problem lösen sollen. Verstehe diese jedoch nicht. Ich probiere mich erst langsam bei WPF aus und bin dort noch absoluter Anfänger.
    Aktuell habe ich ne Form mit nem Menü und einem "Speichern" Knöpfchen im Menü, sowie zwei weitere Knöppels (Add und Remove).
    Beiden habe ich ein Icon zugewiesen. Soweit so gut. Wenn ich diese Button jedoch mit der Maus hover (sagt man dat so!?) dann verschwindet das Icon. Nun habe ich herausgefunden dass das ein Standardverhalten ist. Ich verstehe aber die Logik noch nicht, mit der ich dies verhindern kann. Und ich meine wirklich verstehen. Es gibt zich Snippets aber selbst dort bin ich anscheinend zu deppert diese einzufügen.
    Erst einmal wollte ich gerne gezielt für einen Button bei Hover ein Image zuweisen. Sollte ja irgendwie mitm Trigger gehen, wenn ich das richtig verstehe.
    Kann mir hier wer ein wenig Anleitung geben?
    Spoiler anzeigen

    XML-Quellcode

    1. ​<Window x:Class="Serverstatus.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. Title="Serverstatus" Height="350" Width="525" Name="Serverstatus" Icon="/Serverstatus;component/Resources/refresh.ico">
    5. <Grid>
    6. <Grid>
    7. <DockPanel>
    8. <StackPanel>
    9. <Menu DockPanel.Dock="Top">
    10. <MenuItem Header="_Datei">
    11. <MenuItem Name="Save" Height="20" Header="_Save" Click="Save_Click">
    12. <MenuItem.Icon>
    13. <Image Source="/Serverstatus;component/Resources/save.ico" />
    14. </MenuItem.Icon>
    15. </MenuItem>
    16. </MenuItem>
    17. </Menu>
    18. <Grid Height="25">
    19. <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Height="25">
    20. <Button Name="addButton" Width="25">
    21. <Button.Background>
    22. <ImageBrush ImageSource="/Serverstatus;component/Resources/add.ico" />
    23. </Button.Background>
    24. </Button>
    25. <Button Name="removeButton" Margin="1,0,0,0" Width="25">
    26. <Button.Background>
    27. <ImageBrush ImageSource="/Serverstatus;component/Resources/remove.ico" />
    28. </Button.Background>
    29. </Button>
    30. </StackPanel>
    31. </Grid>
    32. </StackPanel>
    33. </DockPanel>
    34. </Grid>
    35. </Grid>
    36. </Window>
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    Oben ist der gesammte Quellcode für den Designer.
    Bei der programmtechnischen Funktionalität hängt es net.
    Müsste reichen wenn du ne WPF Form erstellst und den Code rein kopierst, oder?
    So hab ich WPF zumindest verstanden ^^
    EDIT: Ah stimmt die Resourcen. Moment XD
    Dateien
    • Serverstatus.zip

      (92,42 kB, 226 mal heruntergeladen, zuletzt: )
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    die Button.Triggers-Auflistung ist Müll

    Msdn schrieb:

    Note that the collection of triggers established on an element only supports EventTrigger, not property triggers (Trigger).
    If you require property triggers, you must place these within a style
    or template and then assign that style or template to the element either
    directly through the Style property, or indirectly through an implicit style reference.

    Man muss es also leider in einen Style verpacken - sonst wärs wohl zu einfach :thumbdown:

    XML-Quellcode

    1. <Button Name="addButton" Width="60" >
    2. <Button.Style>
    3. <Style TargetType="Control">
    4. <Setter Property="Background" >
    5. <Setter.Value>
    6. <ImageBrush ImageSource="/Serverstatus;component/Resources/add.ico" />
    7. </Setter.Value>
    8. </Setter>
    9. <Style.Triggers>
    10. <Trigger Property="IsMouseOver" Value="True">
    11. <Setter Property="Background" >
    12. <Setter.Value>
    13. <ImageBrush ImageSource="/Serverstatus;component/Resources/active.ico" />
    14. </Setter.Value>
    15. </Setter>
    16. </Trigger>
    17. </Style.Triggers>
    18. </Style>
    19. </Button.Style>
    20. </Button>
    Beachte auch, dass des Button Background nicht gesetzt sein darf, denn direkt gesetzte Properties kann ein Style-Setter nicht überschreiben.
    Auha...
    Nu geht wohl das Muntere "such die richtige Property" los...
    Mit

    XML-Quellcode

    1. <Button Name="addButton" Width="25">
    2. <Button.Style>
    3. <Style TargetType="Control">
    4. <Setter Property="Background" >
    5. <Setter.Value>
    6. <ImageBrush ImageSource="/Serverstatus;component/Resources/add.ico" />
    7. </Setter.Value>
    8. </Setter>
    9. <Style.Triggers>
    10. <Trigger Property="IsMouseOver" Value="True">
    11. <Setter Property="Background" >
    12. <Setter.Value>
    13. <ImageBrush ImageSource="/Serverstatus;component/Resources/add.ico" />
    14. </Setter.Value>
    15. </Setter>
    16. </Trigger>
    17. </Style.Triggers>
    18. </Style>
    19. </Button.Style>
    20. </Button>

    ist es wohl nicht getan. Das Icon hovert immernoch brav weg. Unglaublich sowas.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    :D du musst mein Code schon richtig einkopieren.

    ich verwende beim hovern ein anderes Icon, nicht dasselbe nochmal

    aber vlt. versteh ich auch nicht recht - bei mir hovert nichts weg.

    Edit: Probier auch mal den hier:

    XML-Quellcode

    1. <Window x:Class="Serverstatus.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. Title="Serverstatus" Height="350" Width="525" Name="Serverstatus" Icon="/Serverstatus;component/Resources/refresh.ico">
    5. <FrameworkElement.Resources>
    6. <Style TargetType="Button">
    7. <Setter Property="Margin" Value="4"/>
    8. <Setter Property="Width" Value="24"/>
    9. <Style.Triggers>
    10. <Trigger Property="IsMouseOver" Value="True">
    11. <Setter Property="Margin" Value="0"/>
    12. <Setter Property="Width" Value="32"/>
    13. </Trigger>
    14. </Style.Triggers>
    15. </Style>
    16. </FrameworkElement.Resources>
    17. <StackPanel>
    18. <Menu >
    19. <MenuItem Header="_Datei">
    20. <MenuItem Height="20" Header="_Save" Click="Save_Click">
    21. <MenuItem.Icon>
    22. <Image Source="/Serverstatus;component/Resources/save.ico" />
    23. </MenuItem.Icon>
    24. </MenuItem>
    25. </MenuItem>
    26. </Menu>
    27. <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Height="25">
    28. <Button >
    29. <Button.Background>
    30. <ImageBrush ImageSource="/Serverstatus;component/Resources/add.ico" />
    31. </Button.Background>
    32. </Button>
    33. <Button>
    34. <Button.Background>
    35. <ImageBrush ImageSource="/Serverstatus;component/Resources/remove.ico" />
    36. </Button.Background>
    37. </Button>
    38. </StackPanel>
    39. </StackPanel>
    40. </Window>
    So wirkt sich der Style gleich auf beide Buttons aus - Ausserdem brauchts nicht so viele Icons, und ich finde Größenveränderung beim Hovern intuitiver als wenn mit dem Bildle die ganze Optik ausgewechselt ist.
    Auch guck mal bischen drauf dass die Container einen Sinn erfüllen - nicht dass du planlos Dockpanels in Grids in Stackpanels in Grids in Stackpanels einschachtelst.

    Und wenn ein FrameworkElement keinen Namen braucht, gib ihm auch keinen.
    Weil beim rumwerkeln damit kann man namenlose Elemente problemlos kopieren, benannte erzeugen sofort einen Fehler, da der Name dann ja doppelt ist.
    Dateien

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

    Hi,

    so ich bin mal wieder im Büro ^^
    Bei dem von mir in #5 geposteten Code sieht es so aus:

    Bei dem von dir hochgeladenen Porjekt sieht es so aus:
    Spoiler anzeigen

    Dann sieht man kurz den Pfeil und dann sieht es so aus:

    Bei deinem EDIT-Code auch das Gleiche:


    Ich werde mir mal den verlinkten Beitrag zur Gemüte führen.

    EDIT: Was ich noch dabei feststelle ist, dass die Buttons beim Hover noch ihre Größe ändern und herum hüppeln.
    Schön dass man sowas auch so einfach in einen Standard-Style für Buttons verpacken kann. Hab ich dennoch mal wieder rückgängig gemacht ;D Ich bemühe mich ja gerade von den unnötigen rumanimieren weg zu kommen.
    Mit den Grids hattest du recht. Waren eindeutig unnötig. Ich habe auch eher rumprobiert wie man die Buttons wie in WindowsForms so verbauen kann dass sie ordentlich mitskalieren. Gerade wenn der Anwender die Windows-Schrift größer stellt, soll das Programm das ja mit möglichst wenig Code realisieren. Und deshalb probier ich mich eigentlich überhaupt mit WPF.
    Das ist aber nen anderes Thema.
    Ich werde gerade narrisch bei den Hover-Effekten.
    Es scheint so, dass er beim beginn des Hovers noch das Bild erkennt welches er zeigen soll, aber wenn die Maus drauf stehen bleibt tritt wohl ein weiteres Event ein, welches das Image wiederum durch diesen schönen blauen Farbverlauf überschreibt.

    EDIT2:
    Es scheint tatswahrhaftig ein zumindest ähnliches Problem wie in dem verlinkten Beitrag zu sein.
    Ich habe hier auch Win7 am laufen. Aber so wirklich eine sinnvolle funktionierende Lösung sehe ich da auf Anhieb auch nicht. Komische Sache.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

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

    Der Image-Bug ist leider nicht dadurch behoben (siehe Screenshot im Expander).
    Ich glaube ich werde von Buttons mit Images Abstand nehmen müssen, was ich sehr schade fände, da nen Icon meist mehr sagt als 1000 Worte.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    wie jetzt - das Image verschwindet, auch wenn es vom Hover-Effekt garnet betroffen ist? probierma diesen Button:

    XML-Quellcode

    1. <Button >
    2. <Button.Background>
    3. <ImageBrush ImageSource="/Serverstatus;component/Resources/remove.ico" />
    4. </Button.Background>
    5. <Button.Style>
    6. <Style TargetType="Button">
    7. <Setter Property="Margin" Value="4"/>
    8. <Setter Property="Width" Value="24"/>
    9. <Style.Triggers>
    10. <Trigger Property="IsMouseOver" Value="True">
    11. <Setter Property="Margin" Value="0"/>
    12. <Setter Property="Width" Value="32"/>
    13. </Trigger>
    14. </Style.Triggers>
    15. </Style>
    16. </Button.Style>
    17. </Button>
    Es gibt neben ImageBrush auch andere Möglichkeiten, Buttons mit Images zu bestücken

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

    Das Image verschwindet sobald man mit der Maus über den Button fährt. Selbst wenn man einen Trigger schreibt der auf das Hover reagiert und gleiches Image zuweisen soll.
    Ich versteh das net wieso er das tut.

    Deinen Code probier ich auch mal eben.

    EDIT:
    Auch der von dir gepostete Code lässt das Image verschwinden.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

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

    Jetzt wirds lustig...
    Ich hab mal etwas umgebaut und nu schaut es so aus:

    XML-Quellcode

    1. ​<Window x:Class="Serverstatus.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. Title="Serverstatus" Height="350" Width="525" Name="Serverstatus" Icon="/Serverstatus;component/Resources/refresh.ico" Loaded="Serverstatus_Loaded">
    5. <StackPanel>
    6. <Menu >
    7. <MenuItem Header="_Datei">
    8. <MenuItem Height="20" Header="_Save" Click="Save_Click">
    9. <MenuItem.Icon>
    10. <Image Source="/Serverstatus;component/Resources/save.ico" />
    11. </MenuItem.Icon>
    12. </MenuItem>
    13. </MenuItem>
    14. </Menu>
    15. <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Height="32">
    16. <Button Width="24" Height="24" Name="addButton" Opacity="1">
    17. <Button.Background>
    18. <ImageBrush ImageSource="/Serverstatus;component/Resources/add.ico"/>
    19. </Button.Background>
    20. <Button.OpacityMask>
    21. <ImageBrush ImageSource="/Serverstatus;component/Resources/add.ico" />
    22. </Button.OpacityMask>
    23. </Button>
    24. <Button Width="24" Height="24" Name="removeButton" Opacity="1">
    25. <Button.Background>
    26. <ImageBrush ImageSource="/Serverstatus;component/Resources/remove.ico"/>
    27. </Button.Background>
    28. <Button.OpacityMask>
    29. <ImageBrush ImageSource="/Serverstatus;component/Resources/remove.ico" />
    30. </Button.OpacityMask>
    31. </Button>
    32. </StackPanel>
    33. </StackPanel>
    34. </Window>

    Das ganze sieht dann so aus:

    Und als Hover:

    Nu wirds langsam echt wirsch.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    ich habs inzwischen auch mit anderem Window-Style getestet - es liegt wirklich daran.
    Die Button-Background-Property ist ganz allgemein zu nix zu gebrauchen, wenn ein Style-Trigger auf einen Button angewendet wird. Dabei ist egal, was der Trigger macht - sobald er triggert wird die gesetzte Background-Property gelöscht und der Default-Button-Background des betreffenden Window-Styles hingemacht.
    :thumbdown:

    Vermutlich ein Bug im generischen Xaml des Button-Controls.
    Nu kann man bei MS das generische Xaml iwo downloaden oder auskopieren, und den Bug fixen. Evtl. gibts da auch was zu im INet.

    Oder man wendet keine Trigger auf Buttons an. Oder man setzt keine Button-Backgrounds.

    ich kann mal was basteln, wo ein Image in den Button-Content gepackt wird - das müsste Trigger-Save sein ;)

    probierma die Button-Leiste so:

    XML-Quellcode

    1. <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Height="25">
    2. <FrameworkElement.Resources>
    3. <Style TargetType="Button">
    4. <Setter Property="Margin" Value="4"/>
    5. <Setter Property="Width" Value="24"/>
    6. <Style.Triggers>
    7. <Trigger Property="IsMouseOver" Value="True">
    8. <Setter Property="Margin" Value="0"/>
    9. <Setter Property="Width" Value="32"/>
    10. </Trigger>
    11. </Style.Triggers>
    12. </Style>
    13. </FrameworkElement.Resources>
    14. <Button>
    15. <Image Source="/Serverstatus;component/Resources/remove.ico" Margin="-4" />
    16. </Button>
    17. <Button>
    18. <Image Source="/Serverstatus;component/Resources/active.ico" Margin="-4" />
    19. </Button>
    20. <Button>
    21. <Image Source="/Serverstatus;component/Resources/inactive.ico" Margin="-4" />
    22. </Button>
    23. </StackPanel>

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