Reputation: 2613
I want to make a button like this:
The first image is a normal button, but the second is a button with mouseEnter event fired. The bottom part of the button in the second image is not clickable and it acts like a tool tip. How can I make this kind of a button? Do I need to use a tool tip? Please give me some code examples.
EDIT:
Here's F Ruffel's code which I modified:
<HeaderedContentControl BorderBrush="Black">
<HeaderedContentControl.Header>
<TextBlock Text="Header Placeholder" Margin="5" />
</HeaderedContentControl.Header>
<StackPanel>
<TextBlock Text="Content Placeholder Line 1" Margin="5" HorizontalAlignment="Center"/>
<TextBlock Text="Content Placeholder Line 2" Margin="5" HorizontalAlignment="Center"/>
<TextBlock Text="Content Placeholder Line 3" Margin="5" HorizontalAlignment="Center"/>
</StackPanel>
<HeaderedContentControl.Style>
<Style TargetType="{x:Type HeaderedContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type HeaderedContentControl}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border x:Name="headerBorder" Grid.Row="0" Grid.Column="0" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}">
<Grid Name="Header">
<Rectangle Fill="White"/>
<ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Header}"/>
</Grid>
</Border>
<Border x:Name="contentBorder" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" Visibility="Collapsed">
<ContentPresenter />
</Border>
<Border x:Name="cutOutBorder" Grid.Row="0" Grid.Column="1" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,0,1" Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="Header" Property="IsMouseOver" Value="True">
<Setter TargetName="headerBorder" Property="BorderThickness" Value="1,1,1,0" />
<Setter TargetName="contentBorder" Property="BorderThickness" Value="1,0,1,1" />
<Setter TargetName="contentBorder" Property="Visibility" Value="Visible" />
<Setter TargetName="cutOutBorder" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</HeaderedContentControl.Style>
</HeaderedContentControl>
</StackPanel>
Now the last problem is: the expanded part pushes all controls down, and that's what I don't want. Please modify this code to make the extended part overlay controls that are below it, just like in the image.
Upvotes: 3
Views: 406
Reputation: 3285
What I like about WPF is that there is a hundred and one ways to do the same thing. In addition to the suggestions above, you could easily style a HeaderedContentControl
to give the desired look and behaviour:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<HeaderedContentControl BorderBrush="Black">
<HeaderedContentControl.Header>
<TextBlock Text="Header Placeholder" Margin="5" />
</HeaderedContentControl.Header>
<StackPanel>
<TextBlock Text="Content Placeholder Line 1" Margin="5" HorizontalAlignment="Center"/>
<TextBlock Text="Content Placeholder Line 2" Margin="5" HorizontalAlignment="Center"/>
<TextBlock Text="Content Placeholder Line 3" Margin="5" HorizontalAlignment="Center"/>
</StackPanel>
<HeaderedContentControl.Style>
<Style TargetType="{x:Type HeaderedContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type HeaderedContentControl}">
<Grid x:Name="outerGrid" Background="Transparent">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border x:Name="headerBorder" Grid.Row="0" Grid.Column="0" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Header}"/>
</Border>
<Border x:Name="contentBorder" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" Visibility="Collapsed">
<ContentPresenter />
</Border>
<Border x:Name="cutOutBorder" Grid.Row="0" Grid.Column="1" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,0,1" Visibility="Collapsed" Background="Transparent" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseLeftButtonUp" SourceName="contentPresenter">
<BeginStoryboard x:Name="makeVisibleBeginStoryboard">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="headerBorder" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Thickness Left="1" Top="1" Right="1" Bottom="0" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentBorder" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Thickness Left="1" Top="0" Right="1" Bottom="1" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="cutOutBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.MouseLeave" SourceName="outerGrid">
<StopStoryboard BeginStoryboardName="makeVisibleBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.MouseEnter" SourceName="cutOutBorder">
<StopStoryboard BeginStoryboardName="makeVisibleBeginStoryboard" />
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</HeaderedContentControl.Style>
</HeaderedContentControl>
</StackPanel>
</Window>
This solution simulates a cut-out portion (which is just a cell in a Grid
). It uses an EventTrigger
so that content is visible when the Header
is clicked, and content is made invisible when the mouse leaves the Grid
hosting the content, or if it enters the cut-out portion.
Although I think this achieves what you are after, I would recommend investigating other approaches like ToolTip
, Adorner
, or a even custom control. Using animations like this always feels like over-kill to me :)
Upvotes: 2
Reputation: 81233
I would suggest you to add an adorner to your button and make it visible on Mouse Enter event and just remove the adorner on Mouse Leave event. In case you are new to Adorner's you can look at the brief overview here and few custom samples here-
http://msdn.microsoft.com/en-us/library/ms743737.aspx
http://denisvuyka.wordpress.com/2007/10/15/wpf-simple-adorner-usage-with-drag-and-resize-operations/
Upvotes: 2
Reputation: 354376
This could be an Expander styled appropriately. Here is an image how it normally looks like, but with templates and styles you can drastically alter the appearance of controls. The behaviour looks like an expander that just expands on hover instead of click, though.
Upvotes: 0
Reputation: 583
I've got a small example that I build myself once. In CSS set #loginBox
to display:none
. Then when a.loginButton
is clicked, let javascript (e.g. jQuery) change display to display:block
<div id="head-login">
<a href="#" id="loginButton"><span>Klanten login</span></a>
<div class="clear"></div>
<div id="loginBox">
<form id="loginForm" action="http://www.dennishunink.nl/dqr/app/login-check.php" method="post">
<fieldset id="body">
<fieldset>
<label for="email">Email Adres</label>
<input type="text" name="email" id="email" />
</fieldset>
<fieldset>
<label for="password">Wachtwoord</label>
<input type="password" name="password" id="password" />
</fieldset>
<input type="submit" id="login" value="Log in" />
<label for="checkbox"><input type="checkbox" id="checkbox" />Onthoudt mij</label>
</fieldset>
<span><a href="#">Wachtwoord vergeten?</a></span>
</form>
</div>
</div>
</div>
Upvotes: -2