Default button handling broken in Custom mode

Mar 20, 2012 at 1:11 PM

In my application I provide my own Ok and Cancel buttons in a DataWindow, so it uses DataWindowMode.Custom.

The Ok button is set as the default but it doesn't get handled when the user presses Enter. The following code from DataWindow.cs is relevant:

if (e.Key == Key.Enter)
{
  if (_defaultOkElement != null)
    {
      _defaultOkElement.GotFocus += OnButtonReceivedFocus;
      _defaultOkElement.Focus();
      e.Handled = true;
    }
  else
    {
      HandleDefaultButton();
      e.Handled = true;
    }
}

HandleDefaultButton is called only if _defaultOkElement is null. HandleDefaultButton does nothing if _defaultOkCommand is null. Since both _defaultXxx variables rely on the built-in buttons collection they are both null and nothing works. Even if it did work it would still not fix the problem of binding not being updated (that only works for built-in buttons).

Perhaps I'm missing something? Is there a better way to achieve what I need?

Coordinator
Mar 20, 2012 at 1:33 PM

You did specify a command for your custom Ok button? In the HandleDefaultButton (which is called as soon as the _defaultOkElement has received the focus), the _defaultOkCommand is excuted. Maybe the CanExecute returns false?

 

        private void HandleDefaultButton()
        {
            if (_defaultOkCommand != null)
            {
                Log.Info("User pressed 'Enter', executing default command");

                // Not everyone is using the ICatelCommand, make sure to check if execution is allowed
                if (_defaultOkCommand.CanExecute(null))
                {
                    _defaultOkCommand.Execute(null);
                }
            }
        }

Coordinator
Mar 20, 2012 at 1:40 PM

The only thing I can imagine is that the control fails to set the focus (but that would be really strange), so this small fix should do the trick:

if (e.Key == Key.Enter)
{
    if (_defaultOkElement != null)
    {
        _defaultOkElement.GotFocus += OnButtonReceivedFocus;
        if (!_defaultOkElement.Focus())
        {
            HandleDefaultButton();
        }

        e.Handled = true;
    }
    else
    {
        HandleDefaultButton();
        e.Handled = true;
    }
}

Mar 20, 2012 at 1:49 PM

Excuse me, but you are missing the point.

  • _defaultOkElement is null so HandleDefaultButton is called.
  • _defaultOkCommand is null so HandleDefaultButton does nothing.

There is a command; it works when you click the button. CanExecute always returns true.

It's only handling Enter that doesn't work.

Coordinator
Mar 20, 2012 at 2:06 PM

I am sorry, wrong interpretation of your question. Are you sure you set the IsDefault on the custom ok button? The DataWindow determines the command like this:

                _defaultOkCommand = (from button in _buttons
                                     where button.IsDefault
                                     select button.Command).FirstOrDefault();

Mar 20, 2012 at 2:12 PM

The problem is that my OK button is not in the _buttons collection so the DataWindow cannot find it.

Coordinator
Mar 20, 2012 at 2:47 PM

I understand, I thought you passed it via the custom buttons. So, if both the _defaultOkElement and _defaultOkCommand are null, you don't want Catel to set e.Handled to true so you can set it yourself, right?

Mar 20, 2012 at 2:51 PM
Edited Mar 20, 2012 at 4:32 PM

Correct! This would fix it:

 

if (e.Key == Key.Enter)
{
  if (_defaultOkElement != null)
    {
      _defaultOkElement.GotFocus += OnButtonReceivedFocus;
      _defaultOkElement.Focus();
      e.Handled = true;
    }
  else if (_defaultOkCommand != null)
    {
      HandleDefaultButton();
      e.Handled = true;
    }
}

Notice the addition of 

 if (_defaultOkCommand != null)

to the else line.

I have tested it by stepping over the 'e.Handled = true' and it works. I still need to fix the binding update problem, but I know how to do that. (I was hoping Catel would provide for it but ... never mind) 

Coordinator
Mar 20, 2012 at 6:50 PM

We needed to release a hotfix due to a SL5 issue, this fix is also included in the 3.0.1 version.

Mar 21, 2012 at 10:12 AM

Many thanks!

That has fixed my problem.