WPF中的关键提示 [英] Key Tips in WPF

查看:82
本文介绍了WPF中的关键提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有与 http://stackoverflow.com/questions/814756/key-tips-in-wpf

当前,我按照常规方法实施 :

Currently, I implementing follow the general approach:

  1. 制作一个 DependencyProperty   in 您可以触发的窗口/顶级控件,例如

  1. Make a DependencyProperty in your Window / top-level control that you can trigger off of, like IsShowingKeyTips. Catch keyboard input to flip this as you deem appropriate.

制作一个 ContentControl 具有两个依赖项属性,例如1)  IsShowingKeyTip  和 2) KeyTipText . 我们称其为 KeyTipContentControl .

Make a ContentControl that has two dependency properties like 1) IsShowingKeyTip and 2) KeyTipText. Let's call this KeyTipContentControl.

编辑 ContentControl 画布  or 您最喜欢的布局容器,使用一些绑定来适当调整其大小,也许会抛出一些负数保证金值.

Edit the ContentControl's ControlTemplate to look how you want. Make it a Canvas or your favorite layout container, use some bindings to size it properly, maybe throw in some negative Margin values.

如果您想花哨的话,请添加以下代码:附加属性  KeyTip.Text 将它们从普通控件冒到 KeyTipContentControl .

If you want to be fancy, make some AttachedProperties like KeyTip.Text to bubble them up from the plain control to the KeyTipContentControl.

在您的XAML中,将控件 希望打开按键提示.设置适当的绑定.

In your XAML, put the ContentControls around the Controls you want the KeyTips on. Set the bindings as appropriate.

但我有一个问题, 关键提示必须 以分层方式工作,这意味着它可以具有多个级别的KeyTips.当前,我没有解决此问题的解决方案.我希望 希望有人可以帮助我解决问题!.

But I have a problem that Key Tips must work in a hierarchical way that mean it can have multiple level of KeyTips. Currenly i have not a solution for resolver this problem. I hope hope someone can help me resolve it !.

我的代码实现遵循通用方法  上方:

My code implement follow the general approach above:

public class KeyTipContentControl : ContentControl
    {

        public static readonly DependencyProperty IsShowingKeyTipProperty = DependencyProperty.Register("IsShowingKeyTip", typeof(Visibility), typeof(KeyTipContentControl),
            new UIPropertyMetadata(Visibility.Collapsed));

        public Visibility IsShowingKeyTip
        {
            get { return (Visibility)GetValue(IsShowingKeyTipProperty); }
            set { SetValue(IsShowingKeyTipProperty, value); }
        }

        public static readonly DependencyProperty KeyProperty = DependencyProperty.Register("Key", typeof(string), typeof(KeyTipContentControl), new UIPropertyMetadata(""));

        public string Key
        {
            get { return (string)GetValue(KeyProperty); }
            set { SetValue(KeyProperty, value); }
        }


        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(KeyTipContentControl), new UIPropertyMetadata(null));

        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        public KeyTipContentControl()
            : base()
        {

        }
    }

and 

public class KeyManagerContainer : ContentControl
    {

        private List<KeyTipContentControl> keyTipContentControls = new List<KeyTipContentControl>();

        private DependencyObject currentElementShowKeyTip;

        private static string keySequence = "";

        public static readonly DependencyProperty IsShowingKeyTipsProperty = DependencyProperty.Register("IsShowingKeyTips", typeof(bool), typeof(KeyManagerContainer), new UIPropertyMetadata(false));

        public bool IsShowingKeyTips
        {
            get { return (bool)GetValue(IsShowingKeyTipsProperty); }
            set { SetValue(IsShowingKeyTipsProperty, value); }
        }

        public KeyManagerContainer()
            : base()
        {

            //EventManager.RegisterClassHandler(typeof(MainWindow),
            //    FrameworkElement.PreviewKeyDownEvent,
            //    new KeyEventHandler(KeyManagerContainerKeyEvent), false);

            KeyDown += KeyManagerContainerKeyEvent;
            MouseDown += KeyManagerContainer_MouseDown;

        }

        private void KeyManagerContainer_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Reset();
        }

        private void KeyManagerContainerKeyEvent(object sender, KeyEventArgs e)
        {
            ProcessKeyboardInput(e);
        }

        public void ProcessKeyboardInput(KeyEventArgs e)
        {
            bool isSuccess = false;
            if (e.IsRepeat) return;
            switch (e.SystemKey)
            {
                case Key.LeftAlt:
                case Key.RightAlt:
                    {
                        ShowKeyTips(this);
                        e.Handled = true;
                        break;
                    }
                default:
                    ProcessInputKey(e, ref isSuccess);
                    e.Handled = true;
                    break;
            }


            if (isSuccess)
            {
                Reset();
            }
        }

        private void ProcessInputKey(KeyEventArgs e, ref bool isSuccess)
        {
            string k = new KeyConverter().ConvertToInvariantString(e.Key);
            keySequence += k;
            List<KeyTipContentControl> keyTipsFilter = new List<KeyTipContentControl>();
            foreach (KeyTipContentControl keyTip in keyTipContentControls)
            {
                if (keySequence.Equals(keyTip.Key, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (keyTip.Command != null)
                    {
                        (keyTip.Content as UIElement).Focus();
                        keyTip.Command.Execute(null);
                        isSuccess = true;
                    }
                    break;
                }
                else if (keyTip.Key.StartsWith(keySequence, StringComparison.InvariantCultureIgnoreCase))
                {
                    keyTipsFilter.Add(keyTip);
                }
            }

            if (keyTipsFilter.Count > 0 && !isSuccess)
            {
                HideCurrentShowingKeyTips();
                keyTipContentControls = keyTipsFilter;
                ShowKeyTips(keyTipsFilter);
            }
            else
                Reset();
        }

        private void ShowKeyTips(DependencyObject dependencyObject)
        {
            if (currentElementShowKeyTip == null)
            {
                currentElementShowKeyTip = dependencyObject;

                GetKeyTipContainers(dependencyObject, ref keyTipContentControls);

                ShowKeyTips(this.keyTipContentControls);
            }
            else
                Reset();

        }

        private void ShowKeyTips(List<KeyTipContentControl> keyTips)
        {
            foreach (KeyTipContentControl keyTip in keyTips)
            {
                keyTip.IsShowingKeyTip = Visibility.Visible;
            }
        }

        private void Reset()
        {
            currentElementShowKeyTip = null;
            keySequence = "";
            HideCurrentShowingKeyTips();
            keyTipContentControls.Clear();
        }

        private void HideCurrentShowingKeyTips()
        {
            foreach (KeyTipContentControl keyTip in keyTipContentControls)
            {
                keyTip.IsShowingKeyTip = Visibility.Collapsed;
            }
        }

        private void GetKeyTipContainers(DependencyObject dependencyObject, ref List<KeyTipContentControl> list)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
            {
                UIElement element = VisualTreeHelper.GetChild(dependencyObject, i) as UIElement;
                if (element != null)
                {
                    if (element is KeyTipContentControl)
                    {
                        KeyTipContentControl keyTipContainer = element as KeyTipContentControl;

                        list.Add(keyTipContainer);
                    }
                    else if (element is KeyManagerContainer)
                    {
                        continue;
                    }
                    else
                    {
                        GetKeyTipContainers(element, ref list);
                    }
                }
            }
        }
    }

感谢大家的支持! style ="color:#222222">

thank the support of the everybody !

推荐答案

让一个字母出现在控件及其容器外部的要求对我来说是装饰.

The requirement to make a letter appear over a control and outside it's container says adorner to me.

您可以使用弹出窗口,但它位于所有内容的顶部,并且不会随控件一起移动.

You could use popup but that goes on top of everything and doesn't move with it's control.

所有这些都可能使您在以后的工作中更加痛苦.

All of which are potentially going to give you pain further down the road.

您可以定义一些基本的contentcontrol,当用户按下alt时显示其装饰.

You could define some base contentcontrol that shows it's adorner when the user hits alt.

这可以满足您的要求,但只需要层次结构即可.

And that could handle your requirement but for the hierarchical thing.

我想您可以在contentcontrol上拥有一个IsAdornerFocused依赖项属性.

I suppose you could have a dependency property IsAdornerFocussed to the contentcontrol.

使它在树上具有这样的控件的情况仅在其父对象被聚焦时才会显示.

Make it so one which has such a control above it in the tree only shows up when it's parent is focussed.

如果他们按该键,则将其聚焦.

Focus it if they press the key.

.

尽管如此,我还是不太喜欢这种多层的东西.

I don't really like the whole idea of this multi layer thing though.


这篇关于WPF中的关键提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆