Fill Eigenschaft eines Path von Style aus ändern?

  • WPF

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von MichaHo.

    Fill Eigenschaft eines Path von Style aus ändern?

    Hi,
    sorry für den komischen Titel...
    Ich möchte in meiner Anwendung die Icons von jetzt Benutzung der Schriftart FontAwesome ändern auf Icons von z.Bsp. materialdesignicons.com/tag/community

    dazu habe ich ja dann zum Beispiel folgendes Icon:

    XML-Quellcode

    1. <Viewbox x:Key="AboutIcon" Width="48" Height="48">
    2. <Canvas Width="24" Height="24">
    3. <Path Data="M13.5,4A1.5,1.5 0 0,0 12,5.5A1.5,1.5 0 0,0 13.5,7A1.5,1.5 0 0,0 15,5.5A1.5,1.5 0 0,0 13.5,4M13.14,8.77C11.95,8.87 8.7,11.46 8.7,11.46C8.5,11.61 8.56,11.6 8.72,11.88C8.88,12.15 8.86,12.17 9.05,12.04C9.25,11.91 9.58,11.7 10.13,11.36C12.25,10 10.47,13.14 9.56,18.43C9.2,21.05 11.56,19.7 12.17,19.3C12.77,18.91 14.38,17.8 14.54,17.69C14.76,17.54 14.6,17.42 14.43,17.17C14.31,17 14.19,17.12 14.19,17.12C13.54,17.55 12.35,18.45 12.19,17.88C12,17.31 13.22,13.4 13.89,10.71C14,10.07 14.3,8.67 13.14,8.77Z"
    4. Fill="{StaticResource CharBlueBrush}" />
    5. </Canvas>
    6. </Viewbox>


    Nun ist hier die Fill Eigenschaft festgelegt auf eine Statische Resource.
    In meinem Button Style benutze ich ein ContentControl um das Icon anzuzeigen

    XML-Quellcode

    1. <Style x:Key="TestIconGrowButton" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseStyle}">
    2. <Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True" />
    3. <Setter Property="Background" Value="Transparent" />
    4. <Setter Property="BorderThickness" Value="0" />
    5. <Setter Property="Padding" Value="25" />
    6. <Setter Property="Margin" Value="0" />
    7. <Setter Property="Width" Value="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" />
    8. <Setter Property="Template">
    9. <Setter.Value>
    10. <ControlTemplate TargetType="{x:Type ButtonBase}">
    11. <Border x:Name="border"
    12. BorderBrush="{TemplateBinding BorderBrush}"
    13. BorderThickness="{TemplateBinding BorderThickness}"
    14. Background="{TemplateBinding Background}"
    15. SnapsToDevicePixels="True">
    16. <Border.RenderTransform>
    17. <ScaleTransform />
    18. </Border.RenderTransform>
    19. <Border.RenderTransformOrigin>
    20. <Point X="0.5" Y="0.5" />
    21. </Border.RenderTransformOrigin>
    22. <Grid>
    23. <Viewbox>
    24. <ContentControl Content="{TemplateBinding Content}" />
    25. </Viewbox>
    26. </Grid>
    27. </Border>
    28. <ControlTemplate.Triggers>
    29. <EventTrigger RoutedEvent="MouseEnter">
    30. <BeginStoryboard>
    31. <Storyboard>
    32. <DoubleAnimation To="1.4" Duration="0:0:0.15" Storyboard.TargetName="border" Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)" />
    33. <DoubleAnimation To="1.4" Duration="0:0:0.15" Storyboard.TargetName="border" Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)" />
    34. </Storyboard>
    35. </BeginStoryboard>
    36. </EventTrigger>
    37. <EventTrigger RoutedEvent="MouseLeave">
    38. <BeginStoryboard>
    39. <Storyboard>
    40. <DoubleAnimation To="1" Duration="0:0:0.15" Storyboard.TargetName="border" Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)" />
    41. <DoubleAnimation To="1" Duration="0:0:0.15" Storyboard.TargetName="border" Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)" />
    42. </Storyboard>
    43. </BeginStoryboard>
    44. </EventTrigger>
    45. <Trigger Property="IsEnabled" Value="False">
    46. <Setter Property="Background" TargetName="border" Value="Transparent"/>
    47. </Trigger>
    48. </ControlTemplate.Triggers>
    49. </ControlTemplate>
    50. </Setter.Value>
    51. </Setter>
    52. </Style>


    im UserControl sieht das dann so aus:

    XML-Quellcode

    1. <Button Content="{StaticResource AboutIcon}" Height="40" Style="{StaticResource TestIconGrowButton}" />



    Was nun, wenn ich aber jetzt den Button nicht in der vorgegeben Farbe haben möchte, sondern eine andere Farbe zuweisen möchte, ohne gleich alle anderen Button auch zu ändern.
    Ich könnte natürlich hergehen und das Icon in 2 Farben erstellen.... gibt es eine bessere Möglichkeit?
    "Hier könnte Ihre Werbung stehen..."
    Hallo

    Im Grunde ist es einfacher als man denkt. Da das bindingsystem sooo flexibel ist kann man dieses direkt verwenden.
    Einfach die Fill Eigenschaft mit Binding auf das "nächste" Control festlegen. Durch die Vererbung kann dennoch gesteuert werden.

    XML-Quellcode

    1. <Viewbox x:Key="AboutIcon" Width="48" Height="48">
    2. <Canvas Width="24" Height="24">
    3. <Path Data="M13.5,4A1.5,1.5 0 0,0 12,5.5A1.5,1.5 0 0,0 13.5,7A1.5,1.5 0 0,0 15,5.5A1.5,1.5 0 0,0 13.5,4M13.14,8.77C11.95,8.87 8.7,11.46 8.7,11.46C8.5,11.61 8.56,11.6 8.72,11.88C8.88,12.15 8.86,12.17 9.05,12.04C9.25,11.91 9.58,11.7 10.13,11.36C12.25,10 10.47,13.14 9.56,18.43C9.2,21.05 11.56,19.7 12.17,19.3C12.77,18.91 14.38,17.8 14.54,17.69C14.76,17.54 14.6,17.42 14.43,17.17C14.31,17 14.19,17.12 14.19,17.12C13.54,17.55 12.35,18.45 12.19,17.88C12,17.31 13.22,13.4 13.89,10.71C14,10.07 14.3,8.67 13.14,8.77Z"
    4. Fill="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Control}}" />
    5. </Canvas>
    6. </Viewbox>


    Die Fill Eigenschaft ist auf Foreground des nächsten Controls im ElementTree gebunden.

    Nun im Button einfach festlegen:

    XML-Quellcode

    1. <Button Content="{StaticResource AboutIcon}" Foreground="Red"/>


    oder auch

    XML-Quellcode

    1. <Button Content="{StaticResource AboutIcon}">
    2. <Button.Foreground>
    3. <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    4. <GradientStop Color="#FF30913D" Offset="0"/>
    5. <GradientStop Color="#FFEA0B0B" Offset="1"/>
    6. </LinearGradientBrush>
    7. </Button.Foreground>
    8. </Button>


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

    Hi @Nofear23m so ganz einfach ist es dann doch nicht.
    Ich hab in meinem Button Style diesen Trigger:

    XML-Quellcode

    1. <ControlTemplate.Triggers>
    2. <EventTrigger RoutedEvent="MouseEnter">
    3. <BeginStoryboard>
    4. <Storyboard>
    5. <ColorAnimation To="{StaticResource DefaultLightBlue}" Duration="0:0:0.3" Storyboard.TargetName="content" Storyboard.TargetProperty="Foreground.Color"/>
    6. </Storyboard>
    7. </BeginStoryboard>
    8. </EventTrigger>
    9. <EventTrigger RoutedEvent="MouseLeave">
    10. <BeginStoryboard>
    11. <Storyboard>
    12. <ColorAnimation To="{StaticResource DefaultMain}" Duration="0:0:0.3" Storyboard.TargetName="content" Storyboard.TargetProperty="Foreground.Color"/>
    13. </Storyboard>
    14. </BeginStoryboard>
    15. </EventTrigger>
    16. <Trigger Property="IsEnabled" Value="False">
    17. <Setter Property="Background" TargetName="border" Value="Transparent"/>
    18. <Setter Property="Foreground" TargetName="content" Value="{StaticResource ForegroundDarkBrush}"/>
    19. </Trigger>
    20. </ControlTemplate.Triggers>


    nun möchte ich, den Style ja so flexibel wie möglich halten. Indem ich zBsp. 4 Button habe und alle 4 haben eine unterschiedliche Farbe.
    Ich müsste im Trigger die Möglichkeit haben, beim MouseLeave wieder auf die Farbe zu wechseln, die der Button vorher hatte, nur wie komme ich da dran?
    Ich hab es mit FindAncestor, Template Binding versucht, das führte alles zu einem Xaml Fehler.

    XML-Quellcode

    1. <Button Height="40" Content="{StaticResource FolderAddIcon}" Style="{StaticResource IconButton}" Foreground="Red"/>
    so erstelle ich den Button, dann müsste bei MouseLeave die Farbe auf Rot wechseln.
    Ist das überhaupt möglich? oder muss ich da mit Code dran?
    "Hier könnte Ihre Werbung stehen..."
    Hallo

    Ohne es nun zu probieren, klappt es denn nicht mit DynamicResource statt StaticResource?

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

    Also, soweit ich beim lesen verstanden habe, darf man in storyboards nicht binden, da binding nicht freezable ist.
    Im Grunde ist es ja auch keine Statische Resource, sondern eigentlich die Color, die ich dem Button gebe.
    Ich könnte natürlich eine Static Resource anlegen, aber dann wäre ja die flexibilität weg.

    Sagen wir ich hab 4 Buttons, die alle den gleichen Style nutzen sollen. Bei allen ist das Icon in der gleichen Farbe, nun will ich aber Button 3 in Rot haben, also ändere ich die Farbe dirkt beim Button.
    Beim Hovern sollen alle Button hellblau werden und dann wieder die ursprünglische Farbe annehmen. Das klappt auch, wenn ich staticresource verwende, nur wie sag ich im Trigger, "guck mal im MouseLeave, welche Color vorher eingestellt war und setze die dann wieder"

    XML-Quellcode

    1. <StackPanel Orientation="Horizontal">
    2. <Button Height="40" Content="{StaticResource FolderAddIcon}" Style="{StaticResource IconButton}" />
    3. <Button Height="40" Content="{StaticResource FolderAddIcon}" Style="{StaticResource IconButton}" />
    4. <Button Height="40" Content="{StaticResource FolderAddIcon}" Style="{StaticResource IconButton}" />
    5. <Button Height="40" Content="{StaticResource FolderAddIcon}" Style="{StaticResource IconButton}" Foreground="Red"/>
    6. </StackPanel>


    hab im Styles dieses versucht, was mir jetzt am logischsten vorkam:

    XML-Quellcode

    1. <ColorAnimation To="{Binding Foreground.Color, ElementName=content}"


    hier nochmal der ganze Style:

    XML-Quellcode

    1. <Style x:Key="IconButton" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseStyle}">
    2. <Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True" />
    3. <Setter Property="Background" Value="Transparent"/>
    4. <Setter Property="BorderThickness" Value="0"/>
    5. <Setter Property="Padding" Value="25"/>
    6. <Setter Property="Margin" Value="0 "/>
    7. <Setter Property="Foreground" Value="{StaticResource ButtonDefaultBrush}"/>
    8. <Setter Property="local:IsBusyProperty.Value" Value="false"/>
    9. <Setter Property="Width" Value="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" />
    10. <Setter Property="Template">
    11. <Setter.Value>
    12. <ControlTemplate TargetType="{x:Type ButtonBase}">
    13. <Border x:Name="border"
    14. BorderBrush="{TemplateBinding BorderBrush}"
    15. BorderThickness="{TemplateBinding BorderThickness}"
    16. Background="{TemplateBinding Background}"
    17. SnapsToDevicePixels="True">
    18. <Grid>
    19. <Viewbox>
    20. <ContentControl x:Name="content" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" />
    21. </Viewbox>
    22. </Grid>
    23. </Border>
    24. <ControlTemplate.Triggers>
    25. <EventTrigger RoutedEvent="MouseEnter">
    26. <BeginStoryboard>
    27. <Storyboard>
    28. <ColorAnimation To="{StaticResource DefaultLightBlue}" Duration="0:0:0.3" Storyboard.TargetName="content" Storyboard.TargetProperty="Foreground.Color"/>
    29. </Storyboard>
    30. </BeginStoryboard>
    31. </EventTrigger>
    32. <EventTrigger RoutedEvent="MouseLeave">
    33. <BeginStoryboard>
    34. <Storyboard>
    35. <ColorAnimation To="{Binding Foreground.Color, ElementName=content}" Duration="0:0:0.3" Storyboard.TargetName="content" Storyboard.TargetProperty="Foreground.Color"/>
    36. </Storyboard>
    37. </BeginStoryboard>
    38. </EventTrigger>
    39. <Trigger Property="IsEnabled" Value="False">
    40. <Setter Property="Background" TargetName="border" Value="Transparent"/>
    41. <Setter Property="Foreground" TargetName="content" Value="{StaticResource ForegroundDarkBrush}"/>
    42. </Trigger>
    43. </ControlTemplate.Triggers>
    44. </ControlTemplate>
    45. </Setter.Value>
    46. </Setter>
    47. </Style>
    "Hier könnte Ihre Werbung stehen..."
    Hallo

    Kann es erst am Abend probieren. Im Moment hatte ich auch beim schnell drüberlesen einen Knoten im Hirn.

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

    Hi, ja, sorry... :D
    Ich hab auch schon versucht eine Dynamic Resource anzulegen und diese der TO Eigenschaft zuzuweisen, das geht auch nicht.

    Eigentlich ist es genau das:

    XML-Quellcode

    1. <ColorAnimation To="{Binding Foreground.Color, ElementName=content}"

    was passieren soll, nämlich das die Farbe sich bei MouseLeave wieder auf die des ContentControl zurück setzt.
    So wie ich bisher im Netz gelesen habe scheint es wohl nicht zu gehen.
    Zur Not muss ich halt Colors dafür anlegen und diese dann entsprechend ändern wenn nötig.

    Oder gibt es die Möglichkeit eine Dynamische oder Statische Resource zur Laufzeit zu ändern?

    EDIT: Manchmal ist es doch einfacher als gedacht.... Der Trick ist, die To Eigenschaft im MouseLeave einfach weg zu lassen, dann kehrt er nämlich auf die vorher eingestellte Color zurück....

    XML-Quellcode

    1. <EventTrigger RoutedEvent="MouseLeave">
    2. <BeginStoryboard>
    3. <Storyboard>
    4. <ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="content" Storyboard.TargetProperty="Foreground.Color"/>
    5. </Storyboard>
    6. </BeginStoryboard>
    7. </EventTrigger>

    "Hier könnte Ihre Werbung stehen..."

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

    Hallo

    Genau. Ohne einer der beiden Eigenschaften greifen die "Defaults".

    Ist das problem damit behoben?

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

    Hi,
    supi, ja, ich teste noch. Bin noch nicht ganz froh damit, beim toggle button klappt das so noch nicht. Aber egal, ich baue mir gerade einige Styles die ich dann in mein Resources Projekt auslagern kann. Ich ändere dann halt die DefaultColors wenn ich ne andere Farbe vom Icon haben will. Die Icons hab ich mir heute schon alle erstellt
    "Hier könnte Ihre Werbung stehen..."