Maxim Hash
Maxim Hash

Reputation: 405

XAML expandable button/menu item on mouse over

I'm pretty much new to XAML and I'm trying to mimic following => menu example menu (menu items I'm talking about google, facebook etc.)

Expected Behaviour:

  1. Hoover on below Button

enter image description here

  1. Should look like:

enter image description here

My code gives me only:

enter image description here

How do I achieve the expected output - make my TextBlock to appear and be part of the button?

My first approach was to use a grid and create two columns and have the second one always hidden and show only on hoover. Then I came up with belows button approach finally I found out about Expander class... Not sure whats the correct approach, below it's what I have so far, obviously far away from expected output.

<Button Name="button1" Width="170" Height="170" Cursor="Hand">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
    <Image Width="48" Height="48"  Source="https://pbs.twimg.com/profile_images/638750728354430976/HnTYCHzN_400x400.png" />
    <TextBlock Visibility="Hidden" Width="100" Height="70" VerticalAlignment="Center" HorizontalAlignment="Center" Background="pink">
        MenuItem1
        <TextBlock.Style>
            <Style TargetType="TextBlock">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsMouseOver, ElementName=button1}" Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</StackPanel>
<Button.Style>
    <Style TargetType="Button">
        <Setter Property="Background" Value="Green"/>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Margin" Value="20,0,0,0" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Button.Style>

Upvotes: 1

Views: 1922

Answers (2)

Nitin Purohit
Nitin Purohit

Reputation: 18578

You can use animation to achieve this. Below is the Template for Button which uses animation to give Slide-In and Slide-Out effect on MouseEnter and MouseLeave events

   <Button Name="button1"   Cursor="Hand">
        <Button.Template>
            <ControlTemplate>
                <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Image Width="48" Height="48"  Source="https://pbs.twimg.com/profile_images/638750728354430976/HnTYCHzN_400x400.png" />
                    <TextBlock Grid.Column="1" x:Name="myTextBlock" Width="0" Height="48" VerticalAlignment="Center" HorizontalAlignment="Left" Background="pink">
    MenuItem1

                    </TextBlock>
                    <TextBlock Grid.Column="1" Visibility="Hidden"  Width="100" Height="48" x:Name="dummyBlock" />
                </Grid>
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="MouseEnter">
                        <BeginStoryboard>
                            <Storyboard >
                                <DoubleAnimation 
                                    Storyboard.TargetName="myTextBlock" 
                                    Storyboard.TargetProperty="Width" 
                                    From="0.0" 
                                    To="100"
                                    Duration="0:0:0.5" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="MouseLeave">
                        <BeginStoryboard>
                            <Storyboard >
                                <DoubleAnimation 
                                    Storyboard.TargetName="myTextBlock" 
                                    Storyboard.TargetProperty="Width" 
                                    From="100.0" 
                                    To="0"
                                    Duration="0:0:0.3" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Button.Template>
    </Button>

Upvotes: 4

Noam M
Noam M

Reputation: 3164

Here is a fair start for implementing your requirements:

1.The Style uses render transform to stretch your button.

2.The button content changes cording to a bound bool

<UserControl ...>
    <UserControl.Resources>

        <!--*********** Templates ***********-->
        <ControlTemplate x:Key="VIEWALLTemplate">

        </ControlTemplate>
        <ControlTemplate x:Key="DefultTemplate">
            <StackPanel Background="White" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
                <Image Width="48" Height="48"  Source="https://pbs.twimg.com/profile_images/638750728354430976/HnTYCHzN_400x400.png" />
                <TextBlock Text="MenuItem1" Visibility="Hidden" Width="100" Height="70" VerticalAlignment="Center" HorizontalAlignment="Center" Background="pink"/>
            </StackPanel>
        </ControlTemplate>

        <!--*********** Styles ***********-->
        <Style TargetType="Button">
            <Setter Property="Background" Value="Green"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <ScaleTransform ScaleX="2" ScaleY="1"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>

    </UserControl.Resources>

        <Grid>
            <Button Width="100" Height="100" HorizontalAlignment="Center" VerticalAlignment="Center">
                <Button.Content>
                    <ContentControl DataContext="{Binding}" Grid.Row="1">
                        <ContentControl.Style>
                            <Style TargetType="ContentControl">
                                <Setter Property="Template" Value="{StaticResource DefultTemplate}" />
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=SomeBool}" Value="true">
                                        <Setter Property="Template" Value="{StaticResource VIEWALLTemplate}" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </ContentControl.Style>
                    </ContentControl>
                </Button.Content>
            </Button>   
        </Grid>
</UserControl>

Upvotes: 2

Related Questions