JokerMartini
JokerMartini

Reputation: 6157

wpf - How can i control visibility on mousehover of usercontrol?

I have a user control and I want to disable the visibility on a control within the UserControl. I only want it to be visible when the user's cursor is hovering over the main part of the user control which is the 'orange' rectangular part. The red circle is the part of the control which should only be visible on 'hover'

enter image description here

MainWindow.xaml

<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"
        WindowStartupLocation="CenterScreen"
        xmlns:local="clr-namespace:WpfApplication1">
    <Grid>
        <Canvas >
            <Canvas.Background>
                <VisualBrush TileMode="Tile" Stretch="Uniform" Viewport="20,20,20,20" ViewportUnits="Absolute">
                    <VisualBrush.Visual>
                        <Rectangle Width="20" Height="20" Fill="sc#1,0.01,0.01,.01" Stroke="sc#1,0.02,0.02,.02" StrokeThickness="0.1"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Canvas.Background>

            <local:ShapeNode Canvas.Left="117" Canvas.Top="84"/>
            <local:ShapeNode Canvas.Left="242" Canvas.Top="183"/>

        </Canvas>
    </Grid>
</Window>

UserControl - ShapeNode.xaml

<UserControl x:Class="WpfApplication1.ShapeNode"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Ellipse Fill="Red" Opacity=".2" Height="150" Width="150"></Ellipse>
        <Border Margin="5" Height="50" Width="100" Background="#FFDE6119" CornerRadius="5"></Border>
        <TextBlock VerticalAlignment="Center" Background="Transparent" Text="Donuts" HorizontalAlignment="Center"></TextBlock>
    </Grid>
</UserControl>

Upvotes: 3

Views: 8402

Answers (3)

tgpdyk
tgpdyk

Reputation: 1233

I would rather use a control that can be templated within a UserControl. My favorite is a Button -- this is because of the click event if there is any use. But you can use other ones.

<UserControl x:Class="WpfApplication1.ShapeNode"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
  <Button>
    <Button.Template>
        <ControlTemplate>
            <Grid x:Name="MyGrid" >
                <Ellipse x:Name="MyEllipse" Visibility="Hidden" Fill="Red" Opacity=".2" Height="150" Width="150"/>
                <Border Margin="5" Height="50" Width="100" Background="#FFDE6119" CornerRadius="5"></Border>
                <TextBlock VerticalAlignment="Center" Background="Transparent" Text="Donuts" HorizontalAlignment="Center"></TextBlock>
            </Grid>
        <ControlTemplate.Triggers>
            <Trigger SourceName="MyGrid" Property="IsMouseOver" Value="True">
                <Setter TargetName="MyEllipse" Property="Visibility" Value="Visible"></Setter>
            </Trigger>
        </ControlTemplate.Triggers>
        </ControlTemplate>
     </Button.Template>
  </Button>
</UserControl>

Upvotes: 6

AnjumSKhan
AnjumSKhan

Reputation: 9827

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

<Grid x:Name="Grid1" Width="200" Margin="176,197,248,114" d:LayoutOverrides="HorizontalAlignment, VerticalAlignment">
            <Ellipse Fill="Red" Opacity=".2" Height="150" Width="150" Margin="25,0,25,-19"/>
            <Border Margin="50,40.5" Height="50" Width="100" Background="#FFDE6119" CornerRadius="5"/>
            <TextBlock VerticalAlignment="Center" Background="Transparent" Text="Donuts" HorizontalAlignment="Center">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseEnter">
                        <ei:ChangePropertyAction TargetObject="{Binding ElementName=Grid1}" PropertyName="Visibility">
                            <ei:ChangePropertyAction.Value>
                                <Visibility>Collapsed</Visibility>
                            </ei:ChangePropertyAction.Value>
                        </ei:ChangePropertyAction>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </TextBlock>
        </Grid>

Upvotes: 1

ANewGuyInTown
ANewGuyInTown

Reputation: 6477

You could use binding to achieve your result. Bind the visibility property of ellipse to Border in ShapeNode.xaml

Set your border name to e.g. "border1" and put the visibility binding as:

Visibility="{Binding Path=IsMouseOver, ElementName=border1, Converter={StaticResource boolToVisibillityConverter}}"

You have to create a converter to change your boolean to visibility. Use the following converter:

public class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool flag = false;
        if (value is bool)
        {
            flag = (bool)value;
        }
        return (flag ? Visibility.Visible : Visibility.Hidden);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Please note that in your case you have to return hidden not collapsed. Otherwise your border changes position when visibility changes.

Upvotes: 3

Related Questions