Thrash505
Thrash505

Reputation: 379

Change a button's content in a style?

I'm trying to do something similar to this:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
        <Button>
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Content"
                            Value="No mouse over" />
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver"
                                 Value="True">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <CheckBox Content="Mouse is over" />
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
</Window>

However, I get a run-time XamlParseException with a message of:

Cannot add content of type 'System.Windows.Controls.CheckBox' to an object of type 'System.Object'. Error at object 'System.Windows.Controls.CheckBox

I'm actually trying to draw different icons for the button's content depending on external conditions. So I'm actually trying to use a DataTrigger, but the example above simplifies the problem. Any ideas?

Upvotes: 18

Views: 35483

Answers (4)

Steve
Steve

Reputation: 31

If you are making a generic style to be used by buttons all around your app, you will get visual tree conflicts using the approach where the image is a resource. So the template is your only choice in that case.

Upvotes: 3

Rudolf
Rudolf

Reputation: 61

REMARK! Exactly your example works in .NET Framework 4 without any Changes !!!!

  <Button>
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Content"
                        Value="No mouse over" />
                <Style.Triggers>
                    <Trigger Property="IsMouseOver"
                             Value="True">
                        <Setter Property="Content">
                            <Setter.Value>
                                <CheckBox Content="Mouse is over" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

Upvotes: 6

rmoore
rmoore

Reputation: 15393

The actual error is occurring because Visuals can not be directly set as a Setter value. You can get the behavior you are looking for though, by setting the ContentTemplate using a DataTemplate, or by creating your content as a resource, either specific to the button or located elsewhere.

<Button>
    <Button.Resources>
        <CheckBox x:Key="Local_MouseOverContent" Content="Mouse is over" />
    </Button.Resources>
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Content" Value="No mouse over" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Content"
                            Value="{StaticResource Local_MouseOverContent}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

<Button>
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Content" Value="No mouse over" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate DataType="Button">
                                <CheckBox Content="Mouse is over" />
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Upvotes: 40

apandit
apandit

Reputation: 3344

WARNING: This may not be the best or correct way to do it. Make sure you read the other answers on this page as well.

Pretty sure you'd want to use a control template in this sort of situation. Something like:


<style>
    <Setter Property="Content">
        <Setter.Value>
            <ControlTemplate>
                <Image Img="something.jpg" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</style>

And add a control template in the trigger for the on-hover.

Here's a good link

Upvotes: -1

Related Questions