3

I created a Button Template. There are an Image and a Label. The Source of the Image is in a ResourceDictionary Pictures. The Source of the picture is a DrawingImage with White brush color.

<DrawingImage x:Key="Moduly">
  <DrawingImage.Drawing>
    <DrawingGroup>
      <GeometryDrawing Brush="{Binding BackgroundColor}" Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z " />
      <GeometryDrawing Brush="{Binding IconColor}" Geometry="M800.336 949.171H184.527c-80.603 0-136.768-65.56-136.768-146.159V203.677  c0-80.602 56.166-152.42 136.768-152.42h615.809c80.598 0 149.289 71.818 149.289 152.42v599.334  C949.625 883.611 880.934 949.171 800.336 949.171L800.336 949.171z M874.488 203.677c0-39.184-34.99-77.287-74.152-77.287H184.527  c-39.166 0-61.632 38.103-61.632 77.287v599.334c0 39.182 22.466 71.024 61.632 71.024h615.809  c39.162 0 74.152-31.843 74.152-71.024V203.677L874.488 203.677z M273.604 613.832h447.829v75.134H273.604V613.832L273.604 613.832z   M273.604 463.566h447.829v75.131H273.604V463.566L273.604 463.566z M273.604 313.295h447.829v75.134H273.604V313.295  L273.604 313.295z" />                   
    </DrawingGroup>
  </DrawingImage.Drawing>     
</DrawingImage>

The source of all styles (Button, StackPanel, Label) is in resource dictionary Styles.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
  <Style TargetType="Button">
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="Background" Value="#103255"/>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
          <Border Background="{TemplateBinding Background}">
            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    <Style.Resources>        
      <Style TargetType="StackPanel">
        <Style.Resources>
          <Style TargetType="Label">
            <Setter Property="Foreground" Value="White" />
            <Style.Triggers>
              <DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
                           Value="True">
                <Setter Property="Foreground" Value="#103255" />
              </DataTrigger>
            </Style.Triggers>
          </Style>                
        </Style.Resources>
      </Style>
    </Style.Resources>
    <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="True">
        <Setter Property="Background" Value="#103255"/>
        <Setter Property="BorderBrush" Value="Black"/>                
      </Trigger>
      <Trigger Property="IsPressed" Value="True">
        <Setter Property="Background" Value="White"/>
        <Setter Property="BorderBrush" Value="White"/>
      </Trigger>
    </Style.Triggers>
  </Style>        
</ResourceDictionary>

I need to change the brush color of the DrawingImage when the button is pressed. Only the specific one picture inside the pressed button.

<Button Grid.Column="0" Grid.Row="2" Name="modulyButton"
        HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
        BorderThickness="3" Margin="0,0,0,0">
  <StackPanel Orientation="Vertical" Name="modulyStackPanel"
              HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <Image x:Name="modulyImage" Source="{StaticResource Moduly}"
           HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
           Height="30" Width="30"/>
    <Label x:Name="modulyLabel" Content="MODULY"
           VerticalAlignment="Center"/>
  </StackPanel>
</Button>

Does anyone have a solution?

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Pavel Etrich
  • 69
  • 2
  • 9

1 Answers1

4

I think there is no way, with the structure you created. At compile time the Image of the Button knows only that a StaticResource of the correct type has been assigned to its Source property, but it doesn't know that the Source instance has a DrawingGroup with 2 elements which have a Brush property, and so there is no way to call that Brush property in the Image.Triggers. You have to substitute the whole DrawingImage.

My solution (in a simplified form, with Green/Red color switch):

1) Create two DrawingImage, with the same Geometry but different Brush:

<DrawingImage x:Key="Moduly1">
  <DrawingImage.Drawing>
    <DrawingGroup>
      <GeometryDrawing Brush="Green" Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z" />
    </DrawingGroup>
  </DrawingImage.Drawing>
</DrawingImage>

<DrawingImage x:Key="Moduly2">
  <DrawingImage.Drawing>
    <DrawingGroup>
      <GeometryDrawing Brush="Red" Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z" />
    </DrawingGroup>
  </DrawingImage.Drawing>
</DrawingImage>

2) In the Button Template (in the ResourceDictionary) write this on the inner StackPanel style:

<Style TargetType="StackPanel">
  <Style.Resources>
    <Style TargetType="Label">
      <Setter Property="Foreground" Value="White" />
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsPressed,
                        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
                     Value="True">
          <Setter Property="Foreground" Value="#103255" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
    <!-- ADDED PART -->
    <Style TargetType="Image">
      <Setter Property="Source" Value="{StaticResource ResourceKey=Moduly1}"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsPressed,
                        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
                     Value="True">
          <Setter Property="Source" Value="{StaticResource ResourceKey=Moduly2}" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
    <!-- END ADDED PART -->
  </Style.Resources>
</Style>

3) In the particular instance of you Button, remove the Source property from the Image element.

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
  • Thank you. I try your solution and it works! But I have more than one button. I need more general solution. Maybe I should replace Image by ViewBox? In one example I saw there is possibility to fill Path with Binding Color and Source. – Pavel Etrich May 16 '17 at 07:48
  • I guess you want many Buttons all with the same template (a Label and an Image, with that Style, layout, margins, etc), and you want only to change the Label Text and the Image Source from Button to Button (and the command bound to the Button). If you don't want to repeat the xaml of the template every time, I would suggest you to create a UserControl with the code of the Button and with some [DependencyProperty](https://msdn.microsoft.com/en-us/library/ms752914) (like "TextProperty" and "ImageSourceProperty", or whatever), binding these with the properties of the internal components of the UC – Massimiliano Kraus May 16 '17 at 08:06