Search code examples
c#silverlighttriggersgridroutedevent

Silverlight; Change Grid's background on mouseover


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?


Solution

  • 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>