views:

1403

answers:

3

I have a button that I am using on a toolbar that has a nice gradient. I want the button to be completely transparent so that just its contents show against the gradient. When I try, the button appears white rather than being transparent.

The XAML for my button is:

<Button Name="NewAppointmentButton" Style="{StaticResource ToolbarButtonStyle}">
  <TextBlock>X</TextBlock>
</Button>

and the style is:

<Style x:Key="ToolbarButtonStyle" TargetType="Button">
  <Setter Property="Background" Value="Transparent"/>
  <Setter Property="BorderThickness" Value="0"/>
  <Setter Property="Height" Value="24"/>
  <Setter Property="Width" Value="24"/>
</Style>
+2  A: 

The best way is to define a new button template. Adding this to your UserControl.Resources tag should work:

<ControlTemplate x:Key="ButtonControlTemplate1" TargetType="Button">
     <Grid>
      <vsm:VisualStateManager.VisualStateGroups>
       <vsm:VisualStateGroup x:Name="CommonStates">
        <vsm:VisualState x:Name="Normal"/>
        <vsm:VisualState x:Name="MouseOver">
         <Storyboard/>
        </vsm:VisualState>
        <vsm:VisualState x:Name="Pressed">
         <Storyboard/>
        </vsm:VisualState>
        <vsm:VisualState x:Name="Disabled">
         <Storyboard>
          <DoubleAnimationUsingKeyFrames Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity">
           <SplineDoubleKeyFrame KeyTime="0" Value=".55"/>
          </DoubleAnimationUsingKeyFrames>
         </Storyboard>
        </vsm:VisualState>
       </vsm:VisualStateGroup>
       <vsm:VisualStateGroup x:Name="FocusStates">
        <vsm:VisualState x:Name="Focused">
         <Storyboard>
          <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity">
           <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
          </DoubleAnimationUsingKeyFrames>
         </Storyboard>
        </vsm:VisualState>
        <vsm:VisualState x:Name="Unfocused" />
       </vsm:VisualStateGroup>
      </vsm:VisualStateManager.VisualStateGroups>
      <ContentPresenter
       x:Name="contentPresenter"
       Content="{TemplateBinding Content}"
       ContentTemplate="{TemplateBinding ContentTemplate}"
       VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
       HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
       Margin="{TemplateBinding Padding}"/>
      <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
      <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
     </Grid>
    </ControlTemplate>

Now your button should be defined as:

<Button x:Name="NewAppointmentButton" Template="{StaticResource ButtonControlTemplate1}">
    <TextBlock>X</TextBlock>
</Button>

If you're using expression blend you can use it to edit your button template to your heart's content :) Select your button in design view - just above the design window will be a grey button called 'NewAppointmentButton'. Click on it, then 'Edit control parts' then 'Edit template' - the button should get a yellow outline. You can now edit the visual elements and states and transitions.

Good luck!

Mark Pim
Thanks for that. You have many references to "vsm" in this, what namespace do I need for this? (Lots of red squigglies at the moment!)
Ah, sorry! Add xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
Mark Pim
That's super - works a treat! One thing - I tried to set the template within my style (<Setter Property="Template" Value="{StaticResource ToolbarButtonTemplate}"/>) and got an error about not having a resource named ToolbarButtonTemplate (which is the name I used). Do you know why?
I am trying to use this but the resulting button is not clickable by mouse but the keyboard enter/space works. What can I do to make it accept mouse events like enter/leave/move/click?
Vaibhav Garg
A: 

If you want a transparent button with text displayed, why don't you just use a border, unless of course you're taking advantage of the states of the button.

You can just add a border, add your content, set the background on the border to nothing and bada boom, bada bing. One note, rather you will have to have your event listener listen for the MouseLeftButtonDown event rather than the Click event. this is much easier than dorking around with control templates etc.

A: 

I agree with @BigDubb - I think this is the easiest way.

<Border MouseLeftButtonDown="bla_Click" BorderThickness="0" Cursor="Hand">
    ...content here...
</Border>

The optional Cursor property provides visual indication that the area is clickable, which is sometimes not clear from the content of the Border.