Search code examples
wpfgridescapingkeyesc-key

hiding grids using ESC key


I'm new to WPF. I have like 15 grids on my Window and I have a small menu on which I can click and choose which grid to show up or hide. One grid at a time only. I would like that grid to hode (fade out) when I hit Esc. I have all the animations already, I just need to know what grid is visible (active) at the moment.

I don't know how to get current topmost control of my Window.

My solution is when KeyDown event is triggered on my Window to:

private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key == System.Windows.Input.Key.Escape)
        {
            //check all grids for IsVisible and on the one that is true make 
            BeginStoryboard((Storyboard)this.FindResource("theVisibleOne_Hide"));
        }

    }

Solution

  • By active, I assume that means the one that has keyboard focus. If so, the following will return the control that currently has keyboard input focus:

    System.Windows.Input.Keyboard.FocusedElement
    

    You could use it like this:

    if (e.Key == System.Windows.Input.Key.Escape)
    {
        //check all grids for IsVisible and on the one that is true make 
        var selected = Keyboard.FocusedElement as Grid;
        if (selected == null) return; 
    
        selected.BeginStoryboard((Storyboard)this.FindResource("HideGrid"));
    }
    

    An approach that would be more decoupled would be to create a static attached dependency property. It could be used like this (untested):

    <Grid local:Extensions.HideOnEscape="True" .... />
    

    A very rough implementation would look like:

    public class Extensions
    {
        public static readonly DependencyProperty HideOnEscapeProperty = 
           DependencyProperty.RegisterAttached(
               "HideOnEscape", 
               typeof(bool), 
               typeof(Extensions), 
               new UIPropertyMetadata(false, HideOnExtensions_Set));
    
        public static void SetHideOnEscape(DependencyObject obj, bool value)
        {
            obj.SetValue(HideOnEscapeProperty, value);
        }
    
        public static bool GetHideOnEscape(DependencyObject obj)
        {
            return (bool)obj.GetValue(HideOnEscapeProperty);
        }
    
        private static void HideOnExtensions_Set(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var grid = d as Grid;
            if (grid != null)
            {
                grid.KeyUp += Grid_KeyUp;
            }
        }
    
        private static void Grid_KeyUp(object sender, KeyEventArgs e)
        {
            // Check for escape key...
            var grid = sender as Grid;
            // Build animation in code, or assume a resource exists (grid.FindResource())
            // Apply animation to grid
        }
    }
    

    This would remove the need to have code in codebehind.