web-dev-qa-db-ja.com

winformsでComboboxを読み取り専用にする方法

ユーザーがコンボボックスに表示される値を変更できるようにしたくありません。私はEnabled = falseを使用していましたが、テキストがグレー表示されるため、あまり読みやすくありません。 ReadOnly = trueのあるテキストボックスのように動作させたいのですが、テキストは通常​​表示されますが、ユーザーは編集できません。

これを達成する方法はありますか?

53
Kishore A

記事 ComboBox-with-read-only-behavior は、興味深い解決策を示唆しています。

同じ場所に読み取り専用テキストボックスとコンボボックスの両方を作成します。読み取り専用モードが必要な場合はテキストボックスを表示し、編集可能にする場合はコンボボックスを表示します。

18
Joe

DropDownStyleの代わりにDropDownListDropDownプロパティを作成し、TextChangedイベントを処理して、ユーザーがテキストを変更できないようにします。

147
amar vashi

これがあなたが探しているものかどうかわかりませんが...

DropDownStyle = DropDownListを設定します

その後、SelectedIndexChangedイベントで

If (ComboBox1.SelectedIndex <> 0)
{
    ComboBox1.SelectedIndex = 0
}

このい部分は、彼らがそれを変えることができるように「感じる」ということです。値を変更できない理由を伝えるアラートを送信しない限り、彼らはこれがエラーだと考えるかもしれません。

11
Dan Williams

私が提案できる最善の方法は、コンボボックスを読み取り専用のテキストボックス(または単にラベル)に置き換えることです。これにより、ユーザーは引き続き値を選択/コピーすることができます。

もちろん、別の生意気な戦術はDropDownStyleDropDownListに設定し、他のすべてのオプションを削除することです。ユーザーは他に何も選択できません;-p

9
Marc Gravell

ここにリンクの説明を入力

DropDownStyleDropDownListに変更するだけです。または、完全に読み取り専用にする場合は、Enabled = false、またはその外観が気に入らない場合は、読み取り専用のテキストボックスとコンボボックスの2つのコントロールがあり、コンボを非表示にしてテキストボックスを完全に読み取り専用にする必要がある場合は表示します。

8
Virus

ComboBoxをサブクラス化して、同じテキストを含むReadOnly TextBoxを設定して表示すると、それ自体を非表示にするReadOnlyプロパティを追加して処理しました。

class ComboBoxReadOnly : ComboBox
{
    public ComboBoxReadOnly()
    {
        textBox = new TextBox();
        textBox.ReadOnly = true;
        textBox.Visible = false;
    }

    private TextBox textBox;

    private bool readOnly = false;

    public bool ReadOnly
    {
        get { return readOnly; }
        set
        {
            readOnly = value;

            if (readOnly)
            {
                this.Visible = false;
                textBox.Text = this.Text;
                textBox.Location = this.Location;
                textBox.Size = this.Size;
                textBox.Visible = true;

                if (textBox.Parent == null)
                    this.Parent.Controls.Add(textBox);
            }
            else
            {
                this.Visible = true;
                this.textBox.Visible = false;
            }
        }
    }
}
4
CrazyHorse

Michael Rのコードは動作しますが、...
ReadOnlyプロパティがfalseに設定されている場合、_DropDownHeight = 1;_はデフォルト値に戻す必要があります。したがって、base.OnDropDown(e)の前に挿入します:_DropDownHeight = 106;_

_using System;
using System.Threading;
using System.Windows.Forms;

namespace Test_Application
{
    class ReadOnlyComboBox : ComboBox
    {
        private bool _readOnly;
        private bool isLoading;
        private bool indexChangedFlag;
        private int lastIndex = -1;
        private string lastText = "";

        public ReadOnlyComboBox()
        {
        }

        public bool ReadOnly
        {
            get { return _readOnly; }
            set { _readOnly = value; }
        }

        protected override void OnDropDown (EventArgs e)
        {
            if (_readOnly)
            {
                DropDownHeight = 1;
                var t = new Thread(CloseDropDown);
                t.Start();
                return;
            }
            DropDownHeight = 106; //Insert this line.
            base.OnDropDown(e);
        }

        private delegate void CloseDropDownDelegate();
        private void WaitForDropDown()
        {
            if (InvokeRequired)
            {
                var d = new CloseDropDownDelegate (WaitForDropDown);
                Invoke(d);
            }
            else
            {
                DroppedDown = false;
            }
        }
        private void CloseDropDown()
        {
            WaitForDropDown();
        }

        protected override void OnMouseWheel (MouseEventArgs e)
        {
            if (!_readOnly) 
                base.OnMouseWheel(e);
        }

        protected override void OnKeyDown (KeyEventArgs e)
        {
            if (_readOnly)
            {
                switch (e.KeyCode)
                {
                    case Keys.Back:
                    case Keys.Delete:
                    case Keys.Up:
                    case Keys.Down:
                        e.SuppressKeyPress = true;
                        return;
                }
            }
            base.OnKeyDown(e);
        }

        protected override void OnKeyPress (KeyPressEventArgs e)
        {
            if (_readOnly)
            {
                e.Handled = true;
                return;
            }
            base.OnKeyPress(e);
        }
    }
}
_

この回答を完了するには:

ファイル->新規->プロジェクト... Visual C#-> Windows-> Classic Desktop-> Windows Forms Control Library

コントロールの名前を入力します-OK、このコードを貼り付けます。

Dllファイルの名前を選択できます。
プロジェクト-yourprojectプロパティ...

  • アセンブリ名:名前を入力します。ソリューションをビルドするだけで、dllファイルが手に入ります。したがって、読み取り専用コンボを使用するプロジェクトを開き、[参照]を右クリックします。
  • 参照を追加...し、dllファイルを参照します。カスタムコンポーネントをツールボックスに挿入するには、ツールボックスを開き、[全般]タブを右クリックして[アイテムを選択...]を選択します。
  • Dllファイルを参照します-開きます。これで、プロジェクトでReadOnlyComboBoxを使用できます。 PS:VS2015を使用しています。
2
Fabio

ReadOnly Comboの最適なソリューションは次のとおりです。

private void combo1_KeyPress(object sender, KeyPressEventArgs e)
{
    e.KeyChar = (char)Keys.None;
}

コンボのキー押下は破棄されます。

2
Manish

前景色と背景色を有効なコンボボックスのシステムカラーに変更できますが、これによりユーザーが混乱する可能性があります(変更できない場合にそれを使用する理由)、見た目が良くなります。

1
Tom Anderson

これは、Enabled = Falseを含むComboBoxが読みにくいという事実に対処する方法です。

無効になっている場合は適切に見えるコンボボックス

1
Neolisk

DropdownStyleプロパティをSimpleに設定します

ComboBoxのKeyPressイベントに以下のコードを追加します

private void comboBoxName_KeyPress(object sender, KeyPressEventArgs e)
{
    e.Handled = true;
    return;
}

ComboBoxのKeyDownイベントに以下のコードを追加します

private void comboBoxName_KeyDown(object sender, KeyEventArgs e)
{
    e.Handled = true;
    return;
}
0
Nalaka526

すでにデータを入力し、適切なアイテムを選択してDropDownListにした場合、次のような拡張メソッドを使用して、選択リストを選択したアイテムだけにすばやく縮小できます。

public static void MakeReadOnly(this ComboBox pComboBox) {
   if (pComboBox.SelectedItem == null)
      return;

   pComboBox.DataSource = new List<object> {
      pComboBox.SelectedItem
   };
}
0
Dave Cousineau

コードの最も簡単な方法

KeyPressまたはKeyDownのメソッドを追加する代わりに、 '_Form1_Load_'メソッドに次のコードを追加します。

comboBox1.KeyPress += (sndr, eva) => eva.Handled = true;

または

comboBox1.KeyDown += (sndr, eva) => eva.SuppressKeyPress = true;

_(sndr, eva)_は_(object sender, EventArgs e)_用です

0
snir

私はパーティーに少し遅れていることを知っていますが、この正確な質問を調査していたので、コンボボックスをテキストボックスのように読み取り専用にし、リストがポップアップするのを無効にする方法が必要であることがわかりました。それは完璧ではありませんが、インターネット上で見つけたすべての答えよりも、私にとってはうまくいかないことは間違いありません。ボタンが押されてOnDropDownが呼び出されると、DroppedDownプロパティをfalseに設定する新しいスレッドが作成され、「何も起こらない」という効果が作成されます。マウスホイールが消費され、キーイベントも消費されます。

using System;
using System.Threading;
using System.Windows.Forms;

namespace Test_Application
{
    class ReadOnlyComboBox : ComboBox
    {
        private bool _readOnly;
        private bool isLoading;
        private bool indexChangedFlag;
        private int lastIndex = -1;
        private string lastText = "";

        public ReadOnlyComboBox()
        {
        }

        public bool ReadOnly
        {
            get { return _readOnly; }
            set { _readOnly = value; }
        }

        protected override void OnDropDown(EventArgs e)
        {
            if (_readOnly)
            {
                DropDownHeight = 1;
                var t = new Thread(CloseDropDown);
                t.Start();
                return;
            }
            base.OnDropDown(e);
        }

        private delegate void CloseDropDownDelegate();
        private void WaitForDropDown()
        {
            if (InvokeRequired)
            {
                var d = new CloseDropDownDelegate(WaitForDropDown);
                Invoke(d);
            }
            else
            {
                DroppedDown = false;
            }
        }
        private void CloseDropDown()
        {
            WaitForDropDown();
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (!_readOnly) 
                base.OnMouseWheel(e);
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (_readOnly)
            {
                switch (e.KeyCode)
                {
                    case Keys.Back:
                    case Keys.Delete:
                    case Keys.Up:
                    case Keys.Down:
                        e.SuppressKeyPress = true;
                        return;
                }
            }
            base.OnKeyDown(e);
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (_readOnly)
            {
                e.Handled = true;
                return;
            }
            base.OnKeyPress(e);
        }
    }
}
0
Michael R

実際、かなり単純です:

Private Sub combobox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles combobox1.KeyDown
    ' the following makes this the combobox read only    
    e.SuppressKeyPress = True    
End Sub
0
Rob

テキストボックスを使用しないのはなぜですか。テキストボックスには "読み取り専用"プロパティがあり、コンボボックスにデータのみを表示するため、コンボボックスが必要な理由がわかりません。

別の方法は、「on value changed」イベントの入力をキャンセルするだけです。そうすれば、ユーザーが何をするかに関わらず、情報を表示できます...

0
David Božjak