none
DataGridの指定セルを入力不可に設定したい RRS feed

  • 質問

  • お世話になっております。

    早速ですが、DataGridの指定セルを入力不可(表示のみ)に設定したいのですが、

    どうすればよいか行き詰まっています。

    列のReadOnly設定はできますが、全列ではなく、特定のセルだけをReadOnlyに

    設定したいのです。

     

    色々試してみましたが、あまりにも力不足で検討もつかない状態です。

    ご存知の方ぜひご教授お願いいたします。

     

    2006年3月25日 16:20

回答

  •  辛島 さんからの引用

            readOnly = true

    お~ぉ、これだけでいけるんですね! 言われてみればその通りです。ありがとうございました。

     にょり さんからの引用

    いえいえ、クリップボードからの入力でも KeyPress イベントは発生しますよ。

    CTR+Vだとキーを押すことになるので発生しますが、マウスでメニューから貼り付けを選ぶと貼り付けられてしまうんです。

     

    2006年3月27日 1:17
    モデレータ

すべての返信

  • DataGrid ではセル単位のスタイルは設定できませんから、列のイベントで特定の行の入力を弾くしかないように思います。

    次の例は1列目の2行目のセルが編集されるときだけ、入力を弾きます。


    private void Form1_Load(object sender, EventArgs e)
    {
        DataGridTableStyle tableStyle = new DataGridTableStyle();
        tableStyle.MappingName = "DataTable1";
        DataGridTextBoxColumn textBoxColumn = new DataGridTextBoxColumn();
        textBoxColumn.MappingName = "Column1";
        textBoxColumn.TextBox.KeyPress += new KeyPressEventHandler(TextBox_KeyPress);
         tableStyle.GridColumnStyles.Add(textBoxColumn);
         dataGrid1.TableStyles.Add(tableStyle);
    }

     


    void TextBox_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (dataGrid1.CurrentRowIndex == 1)
        {
            e.Handled = true;
        }
    }

     

    2006年3月26日 3:02
  • 基本的な考え方はにょりさんと同じなんですが、KeyPressの判断では貼り付けられると入力されてしまうので、根本的には、DataGridTextBoxColumnを継承したクラスで、Editをオーバーライドして、例えば、



    protected override void Edit(CurrencyManager source, int rowNum, 
         Rectangle bounds, bool readOnly, 
         string instantText, bool cellIsVisible) 
    {
        base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
     
        if (rowNum == 1)
               this.TextBox.Enabled = false;
        else
               this.TextBox.Enabled = true;
    }

     


    のようにしてしまえばいいんじゃないかと思います。

    2006年3月26日 13:26
    モデレータ
  • 単に


        if (rowNum == 1)
            readOnly = true;
        base.Edit (source, rowNum, bounds, readOnly, instantText, cellIsVisible);

     

    とか。

    2006年3月26日 20:02
  • trapemiya さん、辛島さんありがとうございます。

    次のコードで確認できました。KeyPress イベントを使う方法に比べて、入力不可が明示できて良いですね。


    private void Form1_Load(object sender, EventArgs e)
    {
        DataGridTableStyle tableStyle = new DataGridTableStyle();
        tableStyle.MappingName = "DataTable1";
        DataGridTextBoxColumnEx textBoxColumn = new DataGridTextBoxColumnEx();
        textBoxColumn.MappingName = "Column1";
        tableStyle.GridColumnStyles.Add(textBoxColumn);
        dataGrid1.TableStyles.Add(tableStyle);
    }

    public class DataGridTextBoxColumnEx : DataGridTextBoxColumn
    {
        protected override void Edit(CurrencyManager source, int rowNum,
             Rectangle bounds, bool readOnly,
             string instantText, bool cellIsVisible)
        {
            if (rowNum == 1)
            {
                readOnly = true;
            }
            base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
        }
    }
     

     trapemiya さんからの引用

    KeyPressの判断では貼り付けられると入力されてしまうので

    いえいえ、クリップボードからの入力でも KeyPress イベントは発生しますよ。

    2006年3月26日 22:11
  • > いえいえ、クリップボードからの入力でも KeyPress イベントは発生しますよ。

    おお、コンテキスト メニューや別の手段からでも発生するんですか! > KeyPress イベント
    知らなかったです。

    2006年3月27日 0:25
  •  辛島 さんからの引用

            readOnly = true

    お~ぉ、これだけでいけるんですね! 言われてみればその通りです。ありがとうございました。

     にょり さんからの引用

    いえいえ、クリップボードからの入力でも KeyPress イベントは発生しますよ。

    CTR+Vだとキーを押すことになるので発生しますが、マウスでメニューから貼り付けを選ぶと貼り付けられてしまうんです。

     

    2006年3月27日 1:17
    モデレータ
  • にょり さん、trapemiya さん、辛島さん、じゃんぬねっと さん

    いろいろ教えていただきありがとうございました。

    ReadOnly設定したいセルの位置が事前にわかる場合、DataGridTextBoxColumnを継承したクラスで、Editをオーバーライドする方法で行けると思います。


    もし、表示された行のAセルの値によって、BセルをReadOnlyにするかを動的に判断
    したい場合はにょりさんの最初のご解答(列のイベントで特定の行の入力を弾く方法)で
    いくしかないと思われますが、この認識でよろしいでしょうか。

     

    2006年3月27日 6:52
  •  trapemiya さんからの引用

    CTR+Vだとキーを押すことになるので発生しますが、マウスでメニューから貼り付けを選ぶと貼り付けられてしまうんです。

     

    おっしゃる通りでした。確認が不十分で申し訳ございません・・・orz

     kimcheenabe さんからの引用

    もし、表示された行のAセルの値によって、BセルをReadOnlyにするかを動的に判断
    したい場合はにょりさんの最初のご解答(列のイベントで特定の行の入力を弾く方法)で
    いくしかないと思われますが、この認識でよろしいでしょうか。

     

    KeyPress イベントではなく、 Enter イベントと ReadOnly プロパティを使えばよいと気がつきました。


    private void Form1_Load(object sender, EventArgs e)
    {
        DataGridTableStyle tableStyle = new DataGridTableStyle();
        tableStyle.MappingName = "DataTable1";
        DataGridTextBoxColumn textBoxColumn = new DataGridTextBoxColumn();
        textBoxColumn.MappingName = "Column1";
        textBoxColumn.TextBox.Enter += new EventHandler(TextBox_Enter);
        tableStyle.GridColumnStyles.Add(textBoxColumn);
        dataGrid1.TableStyles.Add(tableStyle);
    }

    void TextBox_Enter(object sender, EventArgs e)
    {
        if (((TextBox)sender).Text.StartsWith("123") == true)
        {
            ((TextBox)sender).ReadOnly = true;
        }
    }

     

    こんな感じでいかがでしょうか。値が 123 で始まっているときにセルが読み取り専用になります。コンテキストメニューも抑制されます。

    2006年3月27日 13:26
  • にょりさん

    ご提示の通りうまくいきました。

    いろいろ教えていただきありがとうざいました。

     

     

    2006年4月2日 4:28