views:

5115

answers:

6

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"&gt;

    <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?

A: 

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

apandit
This isn't something that works. A ControlTemplate is and should be used to modify the visual structure and behavior of a control, not it's content. Also, the ContentProperty can't even render a ControlTemplate unless you also set up a ContentTemplate for it.
rmoore
As moore said, this doesn't work. You need to set the ContentTemplate property to a DataTemplate.
Wilka
+10  A: 

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>
rmoore
+3  A: 

Both answers posted so far work great and solve my problem.

But, just a tip for others... I just installed Visual Studio 2010 with .NET 4.0 and the code I first posted works just fine. It seems they made significant progress in many areas with these new versions.

EDIT: Make sure you switch your project's Target Platform to .NET 4.0, otherwise you won't see any difference.

Thrash505
+2  A: 

None of them worked for me.

Mmm
A: 

The second one, using a resource, (by rmoore) worked perfectly for me.

dan
A: 

If you 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 choise in that case.

Steve