1

Simply i want to change the Grid's background color (in Silverlight) when the mouse enters and reset it when the mouse leaves. So I tried different ways but no success. Here is what I have tried:

1: using EventTriggers:

<Grid.Triggers>
    <EventTrigger RoutedEvent="MouseEnter">
        <BeginStoryboard Storyboard="{StaticResouce mouseEnter}"/>
    </EventTrigger>
</Grid.Triggers>

this doesn't work and say:

The member "IsMouseOver" is not recognized or is not accessible

2. using Style.Triggers

I tried setting some simple triggers in an Style with TargetType="Grid" but in Silverlight it seems there is no way to make Style.Triggers in XAML. Here is the code:

<Grid.Style>
    <Style TargetType="Grid">
        <Style.Triggers>
        </Style.Triggers>
    </Style>
</Grid.Style>

But it says:

The attachable property 'Triggers' was not found in type 'Style'.

3. using interaction libraries

I also used Interactivity.dll and interaction.dll but they didnt' work too.

Can anyone help how to change the grid background when the mouse enters in Silverlight?

Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116

1 Answers1

1

There are three possible solutions:

First solution: Using VisualSates: Changing a Background on MouseOver in Silverlight can be done via VisualStates. Here is an example:

<UserControl class="MyUserControlWithVisualStates">
    <Grid x:Name="RootGrid" Background="UglyRed">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="Disabled"/>
                <VisualState x:Name="MouseOver">
                  <Storyboard>
                    <ColorAnimation To="Green"
                 Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
                 Storyboard.TargetName="RootGrid"/>
                  </Storyboard>
                </VisualState>
            </VisualStateGroup>

            <VisualStateGroup x:Name="FocusStates">
                <VisualState x:Name="Focused"/>
                <VisualState x:Name="Unfocused"/>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <OtherGridContent ... />

    </Grid>
</UserControl>

and code behind:

public partial class MyUserControlWithVisualStates : UserControl
{
    private bool m_isMouseOver;
    public MyUserControlWithVisualStates()
    {
        InitializeComponent();
        RootGrid.MouseEnter += OnRootGridMouseEnter;
        RootGrid.MouseLeave += OnRootGridMouseLeave;
    }

    private void UpdateVisualStates()
    {
        if ( m_isMouseOver )
            VisualStateManager.GoToState( this, "MouseOver", true );
        else
            VisualStateManager.GoToState( this, "Normal", true );
    }

    private void OnRootGridMouseLeave( object sender, MouseEventArgs e )
    {
        m_isMouseOver = false;
        UpdateVisualStates();
    }

    private void OnRootGridMouseEnter( object sender, MouseEventArgs e )
    {
        m_isMouseOver = true;
        UpdateVisualStates();
    }
}

Second solution: Changing properties via codebehind: The MouseEnter and MouseLeave event handlers can just change the grid's background color.

public partial class MyUserControl : UserControl
{
    private bool m_isMouseOver;
    public MyUserControl()
    {
        InitializeComponent();
        RootGrid.MouseEnter += OnRootGridMouseEnter;
        RootGrid.MouseLeave += OnRootGridMouseLeave;
    }

    private void UpdateBackground()
    {
        if (m_isMouseOver)
            ((SolidColorBrush) RootGrid.Background).Color = Colors.Red;
        else
            ((SolidColorBrush) RootGrid.Background).Color = Colors.Green;
    }

    private void OnRootGridMouseLeave( object sender, MouseEventArgs e )
    {
        m_isMouseOver = false;
        UpdateBackground();
    }

    private void OnRootGridMouseEnter( object sender, MouseEventArgs e )
    {
        m_isMouseOver = true;
        UpdateBackground();
    }
}

Third solution: Using triggers and actions in xaml:

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

<Grid x:Name="TheGrid" Background="Blue">
    <Grid.Resources>
        <SolidColorBrush x:Key="MouseOverBrush" Color="Green"/>
        <SolidColorBrush x:Key="NormalBrush" Color="Red"/>
    </Grid.Resources>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseEnter" SourceName="TheGrid">
            <ei:ChangePropertyAction
                TargetName="TheGrid"
                PropertyName="Background"
                Value="{StaticResource MouseOverBrush}"/>
        </i:EventTrigger>
        <i:EventTrigger EventName="MouseLeave" SourceName="TheGrid">
            <ei:ChangePropertyAction
                TargetName="TheGrid"
                PropertyName="Background"
                Value="{StaticResource NormalBrush}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Grid>
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
Martin
  • 5,714
  • 2
  • 21
  • 41
  • OK, this is how to define states, now the Q is how to change it? is it possible to change it via XAML coding? – Hossein Narimani Rad Oct 22 '14 at 12:08
  • @HosseinNarimaniRad: If you defined the group "CommonStates" (Normal, Disabled, MouseOver) for your control the states are switched automatically by framework code. Only if you define other VisualStateGroups you have to switch the corresponding states in codebehind via calls to VisualStateManager.GotoState() – Martin Oct 22 '14 at 12:50
  • I tested your code and it is not working. have tried it? – Hossein Narimani Rad Oct 22 '14 at 12:53
  • Sorry, I was wrong about the automatic state change. It only happens automatically if you derive from controls that do some VisualState switching for the CommonStates group (like ToggleButton) because then you inherit the state switching code. – Martin Oct 22 '14 at 13:15
  • @HosseinNarimaniRad: OK, I corrected my answer and added more possible solutions, have a look and decide which one you like the most. – Martin Oct 22 '14 at 13:58
  • Great answer. The third solution won't work. but if you set the background property to something in the grid's definition it will work. so I edited your answer. – Hossein Narimani Rad Oct 22 '14 at 18:20