WPF menu shortcut keys
(Created page with "When designing actions you can enter shortcut keys like ctrl-S. These shortcuts are set per action. There has been issues with WPF not listening to these shortcuts - and it s...")
 
(Automatically adding template at the end of the page.)
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
When designing actions you can enter shortcut keys like ctrl-S. These shortcuts are set per action.
When designing actions, you can enter shortcut keys like ctrl-S. These shortcuts are set per action.


There has been issues with WPF not listening to these shortcuts - and it seems that main cause of the problem was that the WPF app lost all keyboard focus. It is still no fully clear to me how this can be - but it easy to see when it happens.
There have been issues with WPF not listening to these shortcuts; it seems that the main cause of the problem was that the WPF app lost all keyboard focus. It is still not fully clear to me how this can be - but it is easy to see when it happens.


The suggested way to deal with the issue is to react to null focus and fix it:
The suggested way to deal with the issue is to react to null focus and fix it:
this.IsKeyboardFocusWithinChanged += (s, e) =>
<pre>
{
      this.IsKeyboardFocusWithinChanged += (s, e) =>
  if (!this.IsActive)
      {
return;
        if (!this.IsActive)
 
          return;
var foc = Keyboard.FocusedElement;
        var foc = Keyboard.FocusedElement;
 
        if (foc == null)
if (foc == null)
        {
 
          Trace.WriteLine("IsKeyboardFocusedChanged NOTHING");
{
          RescueNullFocus();
 
        }
Trace.WriteLine("IsKeyboardFocusedChanged NOTHING");
        else
 
          Trace.WriteLine("IsKeyboardFocusedChanged " + foc.GetType().Name);
RescueNullFocus();
 
}
 
else
 
Trace.WriteLine("IsKeyboardFocusedChanged " + foc.GetType().Name);
 
 
};


      };
</pre>
   
   
This calls the RescueNullFocus method and you can define it like this:
This calls the RescueNullFocus method and you can define it like this:


private void RescueNullFocus()
<pre>
 
    private void RescueNullFocus()
{
    {
 
      new DisplayQueueThis(() =>
new DisplayQueueThis(() =>
      {
 
        if (Keyboard.FocusedElement == null && this.IsActive) // if the keyboard focused is lost - return it to something usefull
{
        {
 
          IInputElement x = null;
if (Keyboard.FocusedElement == null && this.IsActive)  // if the keyboard focused is lost - return it to something usefull
          if (_wecpof.CurrentWindow() != null)
 
            x = (_wecpof.CurrentWindow() as FrameworkElement).PredictFocus(FocusNavigationDirection.Right) as IInputElement;
{
          if (x == null)
 
            x = (_wecpof).PredictFocus(FocusNavigationDirection.Right) as IInputElement;
IInputElement x = null;
          if (x != null) // Got stuck on Menu
 
          {
if (_wecpof.CurrentWindow() != null)
            if (!(x is MenuItem))
 
              Keyboard.Focus(x);
x = (_wecpof.CurrentWindow() as FrameworkElement).PredictFocus(FocusNavigationDirection.Right) as IInputElement;
            else
 
            {
if (x == null)
              // find a non menuitem
 
              var next = x as FrameworkElement;
x = (_wecpof).PredictFocus(FocusNavigationDirection.Right) as IInputElement;
              var stop = next;
 
              while (next != stop && next != null && !(next is MenuItem))
if (x != null) // Got stuck on Menu
                next = next.PredictFocus(FocusNavigationDirection.Right) as FrameworkElement;
 
              if (next != null)
{
                Keyboard.Focus(x);
 
            }
if (!(x is MenuItem))
 
Keyboard.Focus(x);
 
else
 
{
 
// find a non menuitem
 
var next = x as FrameworkElement;
 
var stop = next;
 
while (next != stop && next != null && !(next is MenuItem))
 
next = next.PredictFocus(FocusNavigationDirection.Right) as FrameworkElement;
 
if (next != null)
 
Keyboard.Focus(x);
 
}
 
}
 
}
 
});


}
          }


        }
      });
    }
</pre>
It is also a good idea to call RescueNullFocus at the start of the application.
It is also a good idea to call RescueNullFocus at the start of the application.


A change was also introduced to the your WPF window own the InputBindings instead of the Wecpof. This is done with an extra parameter to _wecpof.EasyInit like this
A change was also introduced to the WPF window to own the InputBindings instead of the WECPOF. This is done with an extra parameter to _wecpof.EasyInit like this:
  _wecpof.EasyInit(_ecospace, false, pathToStyles, thestyle, this/*send in window as command target*/, _targetgroup);
  _wecpof.EasyInit(_ecospace, false, pathToStyles, thestyle, this/*send in window as command target*/, _targetgroup);
[[Category:WPF]]
{{Edited|July|12|2024}}

Latest revision as of 15:50, 10 February 2024

When designing actions, you can enter shortcut keys like ctrl-S. These shortcuts are set per action.

There have been issues with WPF not listening to these shortcuts; it seems that the main cause of the problem was that the WPF app lost all keyboard focus. It is still not fully clear to me how this can be - but it is easy to see when it happens.

The suggested way to deal with the issue is to react to null focus and fix it:

      this.IsKeyboardFocusWithinChanged += (s, e) =>
      {
        if (!this.IsActive)
          return;
        var foc = Keyboard.FocusedElement;
        if (foc == null)
        {
          Trace.WriteLine("IsKeyboardFocusedChanged NOTHING");
          RescueNullFocus();
        }
        else
          Trace.WriteLine("IsKeyboardFocusedChanged " + foc.GetType().Name);

      };

This calls the RescueNullFocus method and you can define it like this:

    private void RescueNullFocus()
    {
      new DisplayQueueThis(() =>
      {
        if (Keyboard.FocusedElement == null && this.IsActive)  // if the keyboard focused is lost - return it to something usefull
        {
          IInputElement x = null;
          if (_wecpof.CurrentWindow() != null)
            x = (_wecpof.CurrentWindow() as FrameworkElement).PredictFocus(FocusNavigationDirection.Right) as IInputElement;
          if (x == null)
            x = (_wecpof).PredictFocus(FocusNavigationDirection.Right) as IInputElement;
          if (x != null) // Got stuck on Menu
          {
            if (!(x is MenuItem))
              Keyboard.Focus(x);
            else
            {
              // find a non menuitem
              var next = x as FrameworkElement;
              var stop = next;
              while (next != stop && next != null && !(next is MenuItem))
                next = next.PredictFocus(FocusNavigationDirection.Right) as FrameworkElement;
              if (next != null)
                Keyboard.Focus(x);
            }

          }

        }
      });
    }

It is also a good idea to call RescueNullFocus at the start of the application.

A change was also introduced to the WPF window to own the InputBindings instead of the WECPOF. This is done with an extra parameter to _wecpof.EasyInit like this:

_wecpof.EasyInit(_ecospace, false, pathToStyles, thestyle, this/*send in window as command target*/, _targetgroup);
This page was edited 98 days ago on 02/10/2024. What links here