views:

269

answers:

1

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

    }
+1  A: 

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
Paul, thank you very much!
Ivan
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
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
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
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
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