none
Keys.Enterがデザイナ上から選べるようにするにはどうすればいいでしょうか RRS feed

  • 質問

  • C# 2017
    .NET Framework 4.5

    TextBoxを継承したコントロールを作成し、特定プロパティにKeysを指定しています。

    [Browsable(true)]
    public Keys[] CustomKeys { get; set; }

    これでデザイナ上で、キーを選択してプロパティ値として複数設定できるようにはなっているのですが、後からEnter(Return)が選べないことに気付きました。
    (細かくは見てませんが、他にも選べないキーがあるようにも見える)

    Enterを選べるようにする方法はないのでしょうか?
    いちいち自前でKeysプロパティを指定した際と同等のエディタを作り上げて、それをKeys列挙型に変換するような実装をするのはいくらなんでも非効率なので。

    2018年9月16日 2:08

回答

  • その非効率という方法を取るのが正しいやり方でしょうね。

    namespace WindowsFormsApp1
    {
        using System;
        using System.Collections.Generic;
        using System.Windows.Forms;
    
        public partial class Form1 : Form
        {
            public Form1()
            {
                PropertyGrid pg = new PropertyGrid();
                pg.Dock = DockStyle.Fill;
                this.Controls.Add(pg);
    
                pg.SelectedObject = new TextBoxEx();
            }
        }
    
        class TextBoxEx : TextBox
        {
            static TextBoxEx()
            {
                var list = new List<Keys>(Hack.KeysEditorKeys);
                if (!list.Contains(Keys.Enter))
                {
                    list.Add(Keys.Enter);
                    Hack.KeysEditorKeys = list.ToArray();
                }
            }
    
            [System.ComponentModel.Browsable(true)]
            public Keys[] CustomKeys { get; set; }
        }
    
        class Hack
        {
            static Hack()
            {
                //System.Drawing.dll参照
                foreach (var fi in typeof(System.Windows.Forms.Design.ShortcutKeysEditor).GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance))
                {
                    foreach (var fi2 in fi.FieldType.GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static))
                    {
                        if (fi2.FieldType == typeof(Keys[]))
                        {
                            keysField = fi2;
                            break;
                        }
                    }
                }
            }
    
            private static System.Reflection.FieldInfo keysField;
    
            public static Keys[] KeysEditorKeys
            {
                get { return (Keys[])keysField.GetValue(null); }
                set
                {
                    if (value == null)
                    {
                        throw new System.ArgumentNullException();
                    }
                    keysField.SetValue(null, value);
                }
            }
        }
    }
    #他のところで誤動作しても知らない

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク takiru 2018年9月16日 10:55
    2018年9月16日 5:52

すべての返信

  • その非効率という方法を取るのが正しいやり方でしょうね。

    namespace WindowsFormsApp1
    {
        using System;
        using System.Collections.Generic;
        using System.Windows.Forms;
    
        public partial class Form1 : Form
        {
            public Form1()
            {
                PropertyGrid pg = new PropertyGrid();
                pg.Dock = DockStyle.Fill;
                this.Controls.Add(pg);
    
                pg.SelectedObject = new TextBoxEx();
            }
        }
    
        class TextBoxEx : TextBox
        {
            static TextBoxEx()
            {
                var list = new List<Keys>(Hack.KeysEditorKeys);
                if (!list.Contains(Keys.Enter))
                {
                    list.Add(Keys.Enter);
                    Hack.KeysEditorKeys = list.ToArray();
                }
            }
    
            [System.ComponentModel.Browsable(true)]
            public Keys[] CustomKeys { get; set; }
        }
    
        class Hack
        {
            static Hack()
            {
                //System.Drawing.dll参照
                foreach (var fi in typeof(System.Windows.Forms.Design.ShortcutKeysEditor).GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance))
                {
                    foreach (var fi2 in fi.FieldType.GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static))
                    {
                        if (fi2.FieldType == typeof(Keys[]))
                        {
                            keysField = fi2;
                            break;
                        }
                    }
                }
            }
    
            private static System.Reflection.FieldInfo keysField;
    
            public static Keys[] KeysEditorKeys
            {
                get { return (Keys[])keysField.GetValue(null); }
                set
                {
                    if (value == null)
                    {
                        throw new System.ArgumentNullException();
                    }
                    keysField.SetValue(null, value);
                }
            }
        }
    }
    #他のところで誤動作しても知らない

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク takiru 2018年9月16日 10:55
    2018年9月16日 5:52
  • 確認してみましたが、実行してPropertyGrid上からやろうとすると出てきましたが、VSデザイナ上ではEnterキーは出せないようですね・・・。
    2018年9月16日 6:50
  • デザイナが読み込んだdllが更新されてないだけでは…


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2018年9月16日 8:35
  • デザインの開き直しだとダメだったのですが、VSを再起動したら動きました。

    ありがとうございました。

    2018年9月16日 10:30