Geoffrey
Geoffrey

Reputation: 976

Popup appearing on mouse over

I want a popup to appear every time I hover a togglebutton. It then needs to stay open until I click somewhere else in the application. The code below works fine on start up but as soon as I check or uncheck the togglebutton the popup refuses to appear. Any ideas on what I'm doing wrong?

The WPF code

        <ToggleButton Name="btnLogFile" Style="{StaticResource StandardToggle}"
                      Grid.Row="1" Grid.Column="3" Margin="0,3,3,0" 
                      MouseEnter="btnLogFile_MouseEnter">
            <Path Margin="7" SnapsToDevicePixels="True" Stretch="Uniform"
                Stroke="{StaticResource TextLight}" StrokeThickness="2">
                <Path.Data>
                    <GeometryGroup FillRule="Nonzero">
                        <PathGeometry Figures="M 0 0 L 20 0 L 20 10 L 30 10 L 30 40 L 0 40 Z" />
                        <PathGeometry Figures="M 20 0 L 22 0 L 30 8 L 30 10" />
                    </GeometryGroup>
                </Path.Data>
            </Path>
        </ToggleButton>
        <Popup Name="popLogFile"
               PlacementTarget="{Binding ElementName=btnLogFile}" Placement="Custom"
               HorizontalOffset="0" VerticalOffset="0"
               MouseLeftButtonDown="popLogFile_MouseLeftButtonDown">
            <Border Background="{StaticResource BackgroundDark}" BorderBrush="{StaticResource TextBoxBorder}" BorderThickness="1"
                    Width="300" Height="Auto">
                <Grid Margin="3">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="3" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="3" />
                        <ColumnDefinition Width="22" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="22" />
                    </Grid.RowDefinitions>

                    <TextBlock Margin="0,1" Grid.Row="0" Grid.Column="0" Foreground="{StaticResource TextLight}" HorizontalAlignment="Right">Directory</TextBlock>
                    <TextBox Name="logfilePath" Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="3"
                             Style="{StaticResource StandardTextBox}"
                             Foreground="{StaticResource TextLight}">
                        C:\logfile.txt
                    </TextBox><!-- Button made invisible for the time being -->
                    <Button Name="btnBrowseLogfile" Style="{StaticResource StandardButton}" Grid.Row="0" Grid.Column="4" Visibility="Collapsed">...</Button>

                </Grid>
            </Border>
        </Popup>

And the togglebutton's mouse event:

    private void btnLogFile_MouseEnter(object sender, MouseEventArgs e)
    {
        this.popLogFile.IsOpen = true;
        this.popLogFile.StaysOpen = false;
    }

Upvotes: 2

Views: 15572

Answers (3)

Frank
Frank

Reputation: 11

You can bind Popup.IsOpen and ToggleButton.IsChecked to the same bool property. See demo code here. http://bit.ly/L5jxFl

Upvotes: 1

Mate
Mate

Reputation: 5284

1) Add event triggers to ToggleButton:

       <ToggleButton Name="btnLogFile" 
                  Style="{StaticResource StandardToggle}"
                  Grid.Row="1" Grid.Column="3" Margin="0,3,3,0" >
        <ToggleButton.Triggers>
            <EventTrigger RoutedEvent="MouseEnter">
                <BeginStoryboard>
                    <Storyboard TargetName="popLogFile" TargetProperty="IsOpen">
                        <BooleanAnimationUsingKeyFrames  FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame
                    KeyTime="00:00:00"
                    Value="True" />
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>

            <EventTrigger RoutedEvent="ToggleButton.Checked">
                <BeginStoryboard>
                    <Storyboard TargetName="popLogFile" TargetProperty="IsOpen">
                        <BooleanAnimationUsingKeyFrames  FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame
                    KeyTime="00:00:00"
                    Value="False" />
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>

            <EventTrigger RoutedEvent="ToggleButton.Unchecked">
                <BeginStoryboard>
                    <Storyboard TargetName="popLogFile" TargetProperty="IsOpen">
                        <BooleanAnimationUsingKeyFrames  FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame
                    KeyTime="00:00:00"
                    Value="False" />
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>

        </ToggleButton.Triggers>

        <Path Margin="7" SnapsToDevicePixels="True" Stretch="Uniform"
        ...

2) Set in XAML StaysOpen="False" :

<Popup Name="popLogFile"
           PlacementTarget="{Binding ElementName=btnLogFile}" Placement="Custom"
           HorizontalOffset="0" VerticalOffset="0"
           StaysOpen="False"
           MouseLeftButtonDown="popLogFile_MouseLeftButtonDown">

3) Remove method btnLogFile_MouseEnter

Upvotes: 4

Fede
Fede

Reputation: 44068

Do not use code to manipulate UIElements. Bind the IsOpen Property of the Popup to the IsMouseOver property of the togglebutton. Or else if you need multiple or more complex conditions, set a Style to the Popup and in the style you can include Triggers or DataTriggers. I suggest you take a look at this WPF Tutorial

Edit:

Should be something like:

<DataTrigger Binding="{Binding IsChecked, ElementName=YourToggleButton}" Value="True">
   <Setter TargetName="ThePopup" Property="IsOpen" Value="True"/>
</DataTrigger>

Upvotes: 4

Related Questions