Search code examples
wpfxamlstylesresourcedictionary

edit style element from button WPF


I have the following style inside a resource dictionay

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="Button">

            <Grid>
                <Rectangle Fill="#262626" Name="Normal"/>
                <Rectangle Fill="#3f3f41" Name="Hover" Visibility="Hidden"/>
                <Rectangle Fill="#007acc" Name="Pressed" Visibility="Hidden"/>

                <Image Name="Icon"/>
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Grid>

            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="Hover" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="Pressed" Property="Visibility" Value="Hidden"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="Hover" Property="Visibility" Value="Hidden"/>
                </Trigger>
            </ControlTemplate.Triggers>

        </ControlTemplate>
    </Setter.Value>
</Setter>

And I need to change the "Source" of the image with name "Icon" from my button (inside my MainWindow.xaml)

        <Button Style="{StaticResource ToolbarButton}">
            <Setter TargetName="Icon" Property="Source" Value=".png"/>
        </Button>

But it gives me the error "Source is not recognized or is not accesible"

How can I change the "Source" attribute of my image with name "Icon" from a button?


Solution

  • WPF controls actually runs in behaviors. Buttons are not intended to have an Image. Although as button is a Contentcontrol you can put anything inside the content of the Button.

    <Button>
    <image ... />
    </Button
    

    In the style above you can use :

            <Grid>
                <Rectangle Fill="#262626" Name="Normal"/>
                <Rectangle Fill="#3f3f41" Name="Hover" Visibility="Hidden"/>
                <Rectangle Fill="#007acc" Name="Pressed" Visibility="Hidden"/>
    
                <Image Name="Icon" Source="{TemplateBinding Tag}" />
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
    
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="Hover" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="Pressed" Property="Visibility" Value="Hidden"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="Hover" Property="Visibility" Value="Hidden"/>
                </Trigger>
            </ControlTemplate.Triggers>
    
        </ControlTemplate>
    </Setter.Value>
    

    Now you can specify the Source in the Tag property of the Button

    But this is not a right way to do. You should use TemplateBinding to the properties that supports the control behaviour. Like TemplateBinding to Background as button supports it, while button doesnt support an Image.

    Let me know if you need anything else.