none
DataGridViewコントロールの入力可能文字の制御について RRS feed

  • 質問

  • DataGridViewコントロールで、入力できる文字種(「数字のみ」「英字のみ」等)の

    制御をしたいと思い、次のページの例を参考に試してみたのですが、

    今一つ正しく機能しません。

     

    数字または一部の文字しか入力できないようにする

    http://jeanne.wankuma.com/tips/textbox/permitchars.html

     

    overrideしたWndProc()で、Windowsメッセージ(キー入力)を捕える事ができない

    のです。

     

    DataGridView.EditModeプロパティの値を「EditOnKeystrokeOrF2」の場合、

    初めに入力したキーのみ捕える事ができるのですが、それ以降は捕える事が

    できません。

    EditModeプロパティの値を「EditOnEnter」の場合、一切捕える事ができません。

     

    皆様、ご教授願えますでしょうか。

     

    環境:

    Windows Vista Ultimate

    Visual Studio 2005 Professional Edition SP1

    .NET Framework 2.0

     

    2007年6月29日 5:41

回答

  • DataGridView であれば、DataGridViewTextBoxEditingControl クラスの方をご覧になった方が良いでしょう。
    2007年6月29日 6:16
  • このページをみてください。

    http://mnow.wankuma.com/cs2005_datagridview_control5.html

     

    DataGridViewコントロールのTextBox(DataGridViewTextBoxColumn)を拡張して、

    自分の機能を実装するにはDataGridViewColumn や DataGridViewCell を継承してプロパティや動作を拡張する

    ことが必要ですが、今回はIDataGridViewEditingControl から派生し、Control を実装するクラスを拡張するだけですので、

    以下のあたりを実装すればいいと思いますよ。

     

    public class MyTextBoxColumn : DataGridViewTextBoxColumn

      public MyTextBoxColumn()

      public override DataGridViewCell CellTemplate
     

    public class MyTextBoxCell : DataGridViewTextBoxCell

      public override void InitializeEditingControl

      public override Type EditType

     

    class MyTextBoxEditingControl : DataGridViewTextBoxEditingControl


    2007年6月29日 14:28
  • 結局簡易版のEditingControlWantsInputKeyは以下のコードでよさそうですね。

    (正しいEditingControlWantsInputKeyは各キーの有効条件も加味したほうがいいです。)

    DataGridViewTextBoxEditingControl.EditingControlWantsInputKey メソッドのHELPの以下の文章を読む限りですが、

    戻り値は false じゃなくて !dataGridViewWantsInputKey が正しそうです。
     

    dataGridViewWantsInputKey
     DataGridView が keyData の処理を必要とする場合は true。それ以外の場合は false。

    戻り値
     指定されたキーが編集コントロールによって処理される通常の入力キーの場合は true。それ以外の場合は false。

     

    Code Snippet
    public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
        switch ((keyData & Keys.KeyCode))
        {
            case Keys.Prior:
            case Keys.Next:
            case Keys.End:
            case Keys.Home:
            case Keys.Left:
            case Keys.Up:
            case Keys.Right:
            case Keys.Down:
            case Keys.Delete:
            case Keys.Return:
            return true;
        }
        return !dataGridViewWantsInputKey;
    }

     

    2007年7月11日 5:36

すべての返信

  • DataGridView であれば、DataGridViewTextBoxEditingControl クラスの方をご覧になった方が良いでしょう。
    2007年6月29日 6:16
  • このページをみてください。

    http://mnow.wankuma.com/cs2005_datagridview_control5.html

     

    DataGridViewコントロールのTextBox(DataGridViewTextBoxColumn)を拡張して、

    自分の機能を実装するにはDataGridViewColumn や DataGridViewCell を継承してプロパティや動作を拡張する

    ことが必要ですが、今回はIDataGridViewEditingControl から派生し、Control を実装するクラスを拡張するだけですので、

    以下のあたりを実装すればいいと思いますよ。

     

    public class MyTextBoxColumn : DataGridViewTextBoxColumn

      public MyTextBoxColumn()

      public override DataGridViewCell CellTemplate
     

    public class MyTextBoxCell : DataGridViewTextBoxCell

      public override void InitializeEditingControl

      public override Type EditType

     

    class MyTextBoxEditingControl : DataGridViewTextBoxEditingControl


    2007年6月29日 14:28
  • じゃんぬねっとさん、えムナウさん、いつもありがとうございます。

    返信遅れましたが、大変参考になりました。

     

    ありがとうございます。

     

     

    追伸

    私自身、次のスレッドも参考にしたので、今後、このスレッドを見る方の

    参考になればと思い、アンカーを残しておきます。

     

    DataGridViewTextBoxColumnの追加プロパティの保存方法について

    http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=999510&SiteID=7

     

    スレッドのタイトルから、質問自体の内容は直接関係ないですが、スレッドに

    載っていたソースが参考になったので。

     

    2007年7月6日 6:33
  • 一旦、解決済みにしたんですが、もう一度質問させてください。

     

    DataGridViewTextBoxColumnの追加プロパティの保存方法について

    http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=999510&SiteID=7

     

    このスレッドのソースを元に、「DataGridViewTextBoxColumn」を継承させてみた

    のですが、ピリオド「.」だけが入力できなくて困っています。

    DataGridViewTextBoxColumnでは問題なく入力できるので、継承した事によって(?)

    何らかの制限が効いている状態になっているんだとは思うのですが、それが何なのか

    よく分からなくて。

     

    ちなみに、ペースト(貼り付け)だと問題なく入力(貼り付け)できます。

    キーボードからの入力ができないのです。

     

    ご教授願えますでしょうか。

     

     

    長くなりますが、ソースをUPします。

     

    //MyTextBoxコントロール

      public class MyTextBoxEditingControl : TextBox, IDataGridViewEditingControl
        {


         private DataGridView dataGridViewControl;
         private bool valueIsChanged = false;
         private int rowIndexNum;

         public object EditingControlFormattedValue {
          get { return this.Text; }
          set {
           if (value is string)
           {
            this.Text = value.ToString();
           }
          }
         }

         public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
         {

          return this.Text;
         }

         public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
         {

          this.Font = dataGridViewCellStyle.Font;
          this.ForeColor = dataGridViewCellStyle.ForeColor;
          this.BackColor = dataGridViewCellStyle.BackColor;
          this.TextAlign = translateAlignment(dataGridViewCellStyle.Alignment);

          MyTextBoxCell cell = EditingControlDataGridView.CurrentCell as MyTextBoxCell;
          MyTextBoxColumn col = cell.OwningColumn as MyTextBoxColumn;
          this.MaxLength = col.MaxInputLength;
         }

         public int EditingControlRowIndex {

          get { return rowIndexNum; }
          set { rowIndexNum = value; }
         }


         public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
         {

          switch (key & Keys.KeyCode) {
           case Keys.Left:
           case Keys.Up:
           case Keys.Down:
           case Keys.Right:
           case Keys.Home:
           case Keys.End:
           case Keys.PageDown:
           case Keys.PageUp:

            return true;

           default:
            return false;
          }

         }

         public void PrepareEditingControlForEdit(bool selectAll)
         {

          if (selectAll)
          {
           this.SelectAll();
          }
         }

         public bool RepositionEditingControlOnValueChange {

          get { return false; }
         }


         public DataGridView EditingControlDataGridView {

          get { return dataGridViewControl; }
          set { dataGridViewControl = value; }
         }


         public bool EditingControlValueChanged {

          get { return valueIsChanged; }
          set { valueIsChanged = value; }
         }


         public Cursor EditingPanelCursor {

          get { return base.Cursor; }
         }


         protected override void OnTextChanged(System.EventArgs e)
         {
          valueIsChanged = true;
          if (dataGridViewControl != null)
          {
           dataGridViewControl.NotifyCurrentCellDirty(true);
          }
          base.OnTextChanged(e);
         }

         private static HorizontalAlignment translateAlignment(DataGridViewContentAlignment align)
         {
          switch (align) {
           case DataGridViewContentAlignment.TopLeft:
           case DataGridViewContentAlignment.MiddleLeft:
           case DataGridViewContentAlignment.BottomLeft:
            return HorizontalAlignment.Left;

           case DataGridViewContentAlignment.TopCenter:
           case DataGridViewContentAlignment.MiddleCenter:
           case DataGridViewContentAlignment.BottomCenter:
            return HorizontalAlignment.Center;

           case DataGridViewContentAlignment.TopRight:
           case DataGridViewContentAlignment.MiddleRight:
           case DataGridViewContentAlignment.BottomRight:
            return HorizontalAlignment.Right;
          }

          return HorizontalAlignment.Left;
         }
        }


        //MyTextBoxCellクラス

        public class MyTextBoxCell : DataGridViewTextBoxCell
        {

         public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
         {

          base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);

          MyTextBoxEditingControl ctl = (MyTextBoxEditingControl)DataGridView.EditingControl;
          ctl.Text = (string)this.Value;
          ctl.MaxLength = this.MaxInputLength;

         }

         public override Type EditType {
          get { return typeof(MyTextBoxEditingControl); }
         }

         public override Type ValueType {
          get { return typeof(string); }
         }


         public override object Clone()
         {
          MyTextBoxCell cloneObj = base.Clone() as MyTextBoxCell;
          cloneObj.MaxInputLength = this.MaxInputLength;
          return cloneObj;
         }

        }

        //MyTextBoxColumnクラス

        public class MyTextBoxColumn : DataGridViewTextBoxColumn
        {

         public MyTextBoxColumn() : base()
         {
          base.CellTemplate = new MyTextBoxCell();
         }

         public override DataGridViewCell CellTemplate {
          get { return base.CellTemplate; }
          set { base.CellTemplate = value; }
         }


         public override object Clone()
         {
          MyTextBoxColumn cloneObj = base.Clone() as MyTextBoxColumn;
          cloneObj.MaxInputLength = this.MaxInputLength;
          return cloneObj;
         }


        }

     

    2007年7月9日 2:07
  • 「MyTextBoxEditingControl.EditingControlWantsInputKey」に次の処理を追加

    したら入力できる様になったのですが。。。

     

              case Keys.Decimal:
                case Keys.OemPeriod:
                    return true;

    「指定されたキーが編集コントロールによって処理される通常の入力キーの場合は true。それ以外の場合は false

    IDataGridViewEditingControl.EditingControlWantsInputKey メソッド

    http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.idatagridvieweditingcontrol.editingcontrolwantsinputkey(VS.80).aspx

    )より

     

    この事より、「true」を返す、というのは何となく正しい対応の様な気がするんですが、

    では、逆に、カンマ「,」やプラス「+」、アットマーク「@」等々は、何故にコーディング

    しなくても入力できるのでしょうか?

     

    今一つ、EditingControlWantsInputKeyメソッドの使い方がよく分らないのですが。

     

    皆様、ご教授願えますでしょうか。

     

    2007年7月9日 4:50
  • EditingControlWantsInputKey の元々のパタメータ値を無視しているのがなんともなんですが。

    元々のdataGridViewWantsInputKeyも以下の場合がTrueですのでいい気もします。

    Keys.Escape
      Keys.Space
      Keys.Prior
      Keys.Next
      Keys.End
      Keys.Home
      Keys.Left
      Keys.Up
      Keys.Right
      Keys.Down
      Keys.Delete
      Keys.F2
      Keys.Tab
      Keys.Return

     

    DataGridViewTextBoxEditingControlを継承しなかったのは単に参考にしたソースが、

    そうしていたからでしょうか?

     

    提示のサイトも元情報は以下のサイトだと思います。

    http://msdn2.microsoft.com/ja-jp/library/7tas5c80(VS.80).aspx

     

    EditingControlWantsInputKey 自体はDataGridView.ProcessKeyPreview メソッドで使って、

    そのキーのイベントをコントロールが処理したことを示します。

    この場合は他のコントロールにイベントが渡らないことになります。

     

    UserControlやFormがほかのコントロールでしょうからKeys.Decimal、Keys.OemPeriodでも問題は発生しません。

    通常はUserControlやFormがキーに反応して何かやっていない限りはこんなことは起こらないはずなんですけどね。

    2007年7月9日 6:20
  • えムナウさん、いつも本当にありがとうございます。

     

    >EditingControlWantsInputKey の元々のパタメータ値を無視しているのがなんともなんですが

    どういう事でしょうか?

    本来なら、

    Keys.Escape~Keys.Return全て、コーディングしておくべきもの、という事でしょうか?

     

    >提示のサイトも元情報は以下のサイトだと思います。

    >http://msdn2.microsoft.com/ja-jp/library/7tas5c80(VS.80).aspx

    はい、多分そうだと思います。

     

    >DataGridViewTextBoxColumnの追加プロパティの保存方法について

    >http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=999510&SiteID=7

    には、VBのコードだけだったので、元情報と思われるページのC#のソースも参考にしながら、

    コーディングしました。

     

    >DataGridViewTextBoxEditingControlを継承しなかったのは単に参考にしたソースが、

    >そうしていたからでしょうか?

    最終的には、次のページに載っているカスタムコントロールを継承するつもりでおります。

     

    数字または一部の文字しか入力できないようにする

    http://jeanne.wankuma.com/tips/textbox/permitchars.html

     

    public class MyTextBox : System.Windows.Forms.TextBox

    {

    }

     public class MyTextBoxEditingControl : MyTextBox, IDataGridViewEditingControl

    {

    }

     

    こんな感じになるかと考えています。

    それで、まずはファーストステップとして、参考にしたコードの通り、単純にTextBoxを継承してみた

    のです。

     

    >通常はUserControlやFormがキーに反応して何かやっていない限りはこんなことは起こらないはず

    つまり、どういう事でしょうか?

    プロジェクトには、Formと、DataGridViewから継承したカスタムコントロールしかありません。

    コーディングしたのは、先にUPしたカスタムコントロールに施したコードのみです。

    Formには何もコーディングしていません。

    にも関わらず、ピリオド「.」が入力できないのは、摩訶不思議な事が起きている、という事でしょうか?

     

    2007年7月9日 7:18
  •  ぶるーの さんからの引用

    >EditingControlWantsInputKey の元々のパタメータ値を無視しているのがなんともなんですが

    どういう事でしょうか?

    本来なら、

    Keys.Escape~Keys.Return全て、コーディングしておくべきもの、という事でしょうか?

    dataGridViewWantsInputKeyパラメータを無視しているという意味ですが、

    Microsoftのサンプルもそうなのでまぁいいかなと。

     

     ぶるーの さんからの引用

    >DataGridViewTextBoxEditingControlを継承しなかったのは単に参考にしたソースが、

    >そうしていたからでしょうか?

    最終的には、次のページに載っているカスタムコントロールを継承するつもりでおります。

     

    数字または一部の文字しか入力できないようにする

    http://jeanne.wankuma.com/tips/textbox/permitchars.html

     

    public class MyTextBox : System.Windows.Forms.TextBox

    {

    }

     public class MyTextBoxEditingControl : MyTextBox, IDataGridViewEditingControl

    {

    }

     

    こんな感じになるかと考えています。

    それで、まずはファーストステップとして、参考にしたコードの通り、単純にTextBoxを継承してみた

    のです。

    了解です。

     

     ぶるーの さんからの引用

    >通常はUserControlやFormがキーに反応して何かやっていない限りはこんなことは起こらないはず

    つまり、どういう事でしょうか?

    プロジェクトには、Formと、DataGridViewから継承したカスタムコントロールしかありません。

    コーディングしたのは、先にUPしたカスタムコントロールに施したコードのみです。

    Formには何もコーディングしていません。

    にも関わらず、ピリオド「.」が入力できないのは、摩訶不思議な事が起きている、という事でしょうか? 

    ちょっと再現試験していないのでわからないですが、不思議な状況ですね。

    2007年7月9日 8:03
  • 結局簡易版のEditingControlWantsInputKeyは以下のコードでよさそうですね。

    (正しいEditingControlWantsInputKeyは各キーの有効条件も加味したほうがいいです。)

    DataGridViewTextBoxEditingControl.EditingControlWantsInputKey メソッドのHELPの以下の文章を読む限りですが、

    戻り値は false じゃなくて !dataGridViewWantsInputKey が正しそうです。
     

    dataGridViewWantsInputKey
     DataGridView が keyData の処理を必要とする場合は true。それ以外の場合は false。

    戻り値
     指定されたキーが編集コントロールによって処理される通常の入力キーの場合は true。それ以外の場合は false。

     

    Code Snippet
    public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
        switch ((keyData & Keys.KeyCode))
        {
            case Keys.Prior:
            case Keys.Next:
            case Keys.End:
            case Keys.Home:
            case Keys.Left:
            case Keys.Up:
            case Keys.Right:
            case Keys.Down:
            case Keys.Delete:
            case Keys.Return:
            return true;
        }
        return !dataGridViewWantsInputKey;
    }

     

    2007年7月11日 5:36
  • えムナウさん、回答ありがとうございます。

     

    期待通りの結果が得られる様になりました。

     

    >EditingControlWantsInputKey メソッドのHELPの以下の文章を読む限り

    ヘルプは読んでたつもりだったんですが、「dataGridViewWantsInputKey」の扱い方を

    理解していなかったみたいです。

    ソースを提示して頂いて、改めてそういう風に使うのか、と理解しました(汗)

     

    何にせよ、マルっと解決できました。

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

     

     

    追伸:

    再質問する際、「ピリオドだけが入力できない」と書きましたが、ピリオド「.」以外に

    「q!"#$%&'()」も入力できない事が分りました。

    ただ今回、えムナウさんが提示して頂いたソースで、全て解決できました。

     

    2007年7月12日 0:31