0

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"));
        }

    }
Ivan
  • 101
  • 3
  • 13

1 Answers1

1

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.

Paul Stovell
  • 32,377
  • 16
  • 80
  • 108
  • I was maybe not so clear in my question but I have other different elements like textBlocks, textBoxes, some dataGrids etc on my Grid that I want to hide with hiding my grid of course, so my grid is not the Keyboard.FocusedElement one, for example, that property's value is this dataGrid control. – Ivan Jan 28 '09 at 13:13
  • I think that I can setup one variable where I can write the name of the textBlock which opens the specific grid, so when ESC gets pressed on Window, I will do switch case and start the animation for the name from the variable. – Ivan Jan 28 '09 at 13:15
  • there is no keyboard navigation through my app so I can know what the user has opened since he has to use OnMouseDown on one of my textBlocks in order to show the grid – Ivan Jan 28 '09 at 13:17
  • Ivan, You can use the VisualTreeHelper.GetParent to walk up the tree. So if your text box had focus, you could recursively call VisualTreeHelper.GetParent until you find a Grid. – Paul Stovell Jan 28 '09 at 13:29
  • Yes, VisualTreeHelper.GetParent that is what I was looking for. I dodn't know about this so I wanted to do a for loop with setting the selectedElement to its parent untill I hit type of Grid, but of course I was unable to get parent the right way. Thanks again. – Ivan Jan 28 '09 at 13:45