none
DataGridViewでReadonlyの列を選択している状態で別スレッドにて画面を表示するとIMEが無効になってしまう RRS feed

  • 質問

  • お世話になります。

    VS2012 C# .NET4.0 で作成をしています。

    DataGridViewでReadonlyの列があり、その列を選択中はIMEが無効になるかと思います。

    その状態で別スレッドにて処理待ちするような画面を表示すると、DataGridViewのIMEが全て無効状態になってしまいます。

    セルを編集状態にすればIMEは機能しますが、IMEがONになっていた状態で編集状態にしないまま「A」キーを3回押すと「aああ」と入力されてしまいます。

    ※Readonly列以外ではこのような現象は出ません。

    以下、コードになります。

    using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication { public partial class Form1 : Form { private DataGridView dataGridView; public Form1() { dataGridView = new DataGridView(); var normalColumn = new DataGridViewTextBoxColumn(); var readOnlyColumn = new DataGridViewTextBoxColumn() { ReadOnly = true }; var button = new Button(); dataGridView.Columns.Add(normalColumn); dataGridView.Columns.Add(readOnlyColumn); dataGridView.Dock = DockStyle.Fill; button.Dock = DockStyle.Bottom; button.Click += button_Click; this.Controls.Add(dataGridView); this.Controls.Add(button); } private void button_Click(object sender, EventArgs e) { Task.Factory.StartNew(() => {                     var form = new Form() { TopMost = true };
                        var dummy = new TextBox() { Width = 0, Height = 0 };
                        form.Controls.Add(dummy);
    form.Show(); Thread.Sleep(500); form.Close(); }); dataGridView.Focus(); } } }

    色々と調査を行いましたが、上記コードで「TopMost = true」がなければ現象は出ません。

    また、別画面でダミーのテキストボックスを入れていますが、このテキストボックスがないと「TopMost = true」がなくてもIMEが無効になってしまいました。

    回避する方法を心当たりある方はご教授頂けると幸いです。よろしくお願いいたします。


    • 編集済み Kinenows 2016年5月31日 23:59
    2016年5月31日 6:22

回答

  • 原因は確定できないですが、とりあえずの回避

    class DataGridViewEx : DataGridView
    {
        protected override bool CanEnableIme
        {
            get
            {
                //DataGridのIMEを無効に切り替えた状態だと今回の問題が発生するので有効にしたままにする
                return true;
            }
        }
    
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (!base.CanEnableIme)//本来IMEが無効になる状態(ReadOnlyのセルにフォーカス)
            {
                if ((keyData & (Keys.Control | Keys.Alt)) == Keys.None)
                {
                    switch (keyData & Keys.KeyCode)
                    {
                    case Keys.Enter:
                    case Keys.Tab:
                    case Keys.Back:
                    case Keys.Escape:
                    case Keys.Left:
                    case Keys.Right:
                    case Keys.Up:
                    case Keys.Down:
                    case Keys.PageUp:
                    case Keys.PageDown:
                    case Keys.Home:
                    case Keys.End:
                    case Keys.Print:
                    case Keys.PrintScreen:
                    case Keys.Insert:
                    case Keys.Delete:
                    case Keys.CapsLock:
                    case Keys.LWin:
                    case Keys.RWin:
                    case Keys.Apps:
                    case Keys.NumLock:
                        break;
                    default:
                        //文字入力は受け付けないようにしてIMEの入力ウィンドウを表示させないようにする
                        return true;
                    }
                }
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
    #IME入力中にセル移動すると入力ウィンドウが出てしまいますが。

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

    • 回答としてマーク 星 睦美 2016年7月22日 4:50
    2016年6月2日 3:59