Fluent.Ribbon icon indicating copy to clipboard operation
Fluent.Ribbon copied to clipboard

KeyTips for standard controls

Open the-madcat opened this issue 9 years ago • 10 comments
trafficstars

Hi use Fluent.Ribbon for the first time and it looks great but I need to show a Slider on a RibbonGroupBox and want to add a KeyTip in order to focus it (just for the sake of completeness). Is there a possibility to do that in XAML?

Environment

  • Fluent.Ribbon v4.0.3.394
  • Theme Office2013 (not needed in version 5.0 and upwards)
  • Windows 8.1
  • .NET Framework 4.5

the-madcat avatar Oct 04 '16 09:10 the-madcat

You should be able to use the KeyTip.Keys attached property. To be able to react to presses you would have to implement IKeyTipedControl. If you are unable to implement IKeyTipedControl for whatever reason, you are currently out of luck.

batzen avatar Oct 06 '16 14:10 batzen

Thank you. I will try that.

the-madcat avatar Oct 10 '16 06:10 the-madcat

I have to admit that I used the Fluent code as template (what I should have done before ...) but this is what worked for me:

public class KeyTipedSlider
    : Slider, IKeyTipedControl
{
    public string KeyTip
    {
        get { return (string)GetValue(KeyTipProperty); }
        set { SetValue(KeyTipProperty, value); }
    }

    public static readonly DependencyProperty KeyTipProperty = 
        Fluent.KeyTip.KeysProperty.AddOwner(typeof(KeyTipedSlider));

    public void OnKeyTipBack() { }

    public void OnKeyTipPressed()
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
            (DispatcherOperationCallback)delegate (object arg)
            {
                var ctrl = (Slider)arg;

                if (!ctrl.IsKeyboardFocusWithin)
                    Keyboard.Focus(ctrl);

                return null;
            }, this);
    }

    public KeyTipedSlider()
    {
        Fluent.KeyTip.SetAutoPlacement(this, false);
        Fluent.KeyTip.SetHorizontalAlignment(this, HorizontalAlignment.Left);
        Fluent.KeyTip.SetVerticalAlignment(this, VerticalAlignment.Top);
        Fluent.KeyTip.SetMargin(this, new Thickness(7, -8, 0, 0));
    }
}

My last question now is why the AutoPlacement does not work.

the-madcat avatar Oct 10 '16 08:10 the-madcat

You set AutoPlacement to false. What behavior do you expect and what does not work as you you expect it?

I added a sample to the showcase which shows that margin works there.

batzen avatar Oct 15 '16 12:10 batzen

I would like to add a screenshot but I am in the middle of a renovation so my computer is not ready right now. I try to describe it:.

All commands I added to the constructor correct the actual AutoPlacement behavior. Without that code the KeyTip was placed centered on the bottom of the RibbonGroupBox to which I added the KeyTipedSilder. First I thought that my Silder somehow took the whole placed within the GroupBox but changing the Background showed that it was placed and sized correctly.

As soon as my computer is ready again I will take a look to the showcase.

the-madcat avatar Oct 17 '16 09:10 the-madcat

Ok, now i get it.

You expect Autoplacement=true to place the KeyTip correctly without having to set it to false and choose your own placement directions. Right?

batzen avatar Oct 18 '16 09:10 batzen

Right!

This was, what I guessed for an AutoPlacement setting. But I even tested my guess by retrieving the AutoPlacement setting of some of the Ribbon controls where it always was true with a KeyTip placement as I tried to imitate with my constructor code.

For some screenshots I played a bit with a small test application and I was a frustrated because the AutoPlacement worked and looked like this: image

That would look very acceptable for me but I had to find out why it did not work in my actual application. I found out that if I add a button everything looks different: image

This was what I experienced in my application and with my corrective code for me it looked correct because I did not know how it looked like without any button: image

Now the big question is: Is it a bug or a feature that I did not understand correctly?

PS:

  1. Wenn ich mal früher auf dein Profilbild geklickt hätte, dann hätten wir das Gespräch auch in Deutsch führen können, falls erwünscht :P
  2. Vielen Dank schon mal für die Zeit, die du bisher in die Beantwortung meiner Fragen investiert hast.

the-madcat avatar Oct 18 '16 22:10 the-madcat

Deutsch wahrscheinlich teils einfacher, allerdings versteht das wahrscheinlich auch nur ein Bruchteil der User. Daher bevorzuge ich, alleine schon aus Gründen der Transparenz, Englisch. ;-)

I did not design that feature myself, so i can't really say if it's intended to work that way or not.

For me it looks more like a layout issue than a feature. Will mark this as a bug and have a look at it at some point in time, but as you currently have a workaround for your situation it will have low priority. ;-)

batzen avatar Oct 27 '16 17:10 batzen

Or if you want to have a look yourself, feel free to propose a solution and a PR afterwards. ;-)

batzen avatar Oct 27 '16 17:10 batzen

Right now I have not that much time but after a bit of debugging I can say this:

In your Fluent.KeyTipAdorner there is a method called UpdateKeyTipPositions().

In case of no auto placement this method goes through a couple of possible cases like if the associated element is a DialogLauncherButton or if it is within a RibbonGallery and so on.

If none of these cases is true there is a last condition that checks if the size of the associated element is not RibbonControlSize.Large and if the associated element is not a Spinner, ComboBox, TextBox or CheckBox. I admit that I did not check this code very thoroughly but the conditions suggest that this case should handle all KeyTip placements for controls shaped like a TextBox. The other case seems to handle all controls with a size set to RibbonControlSize.Large like a Button.

Now because I did not change the size of my KeyTipedSlider and because it is neither a Spinner, ComboBox, TextBox or a CheckBox it is handled like a button. I have no idea why it works without a button in previous position but I know that setting the Size to RibbonControlSize.Middle will do the trick.

the-madcat avatar Oct 29 '16 15:10 the-madcat