ユーザーがコンボボックスに表示される値を変更できるようにしたくありません。私はEnabled = false
を使用していましたが、テキストがグレー表示されるため、あまり読みやすくありません。 ReadOnly = true
のあるテキストボックスのように動作させたいのですが、テキストは通常表示されますが、ユーザーは編集できません。
これを達成する方法はありますか?
記事 ComboBox-with-read-only-behavior は、興味深い解決策を示唆しています。
同じ場所に読み取り専用テキストボックスとコンボボックスの両方を作成します。読み取り専用モードが必要な場合はテキストボックスを表示し、編集可能にする場合はコンボボックスを表示します。
DropDownStyle
の代わりにDropDownList
にDropDown
プロパティを作成し、TextChanged
イベントを処理して、ユーザーがテキストを変更できないようにします。
これがあなたが探しているものかどうかわかりませんが...
DropDownStyle = DropDownListを設定します
その後、SelectedIndexChangedイベントで
If (ComboBox1.SelectedIndex <> 0)
{
ComboBox1.SelectedIndex = 0
}
このい部分は、彼らがそれを変えることができるように「感じる」ということです。値を変更できない理由を伝えるアラートを送信しない限り、彼らはこれがエラーだと考えるかもしれません。
私が提案できる最善の方法は、コンボボックスを読み取り専用のテキストボックス(または単にラベル)に置き換えることです。これにより、ユーザーは引き続き値を選択/コピーすることができます。
もちろん、別の生意気な戦術はDropDownStyle
をDropDownList
に設定し、他のすべてのオプションを削除することです。ユーザーは他に何も選択できません;-p
DropDownStyle
をDropDownList
に変更するだけです。または、完全に読み取り専用にする場合は、Enabled = false
、またはその外観が気に入らない場合は、読み取り専用のテキストボックスとコンボボックスの2つのコントロールがあり、コンボを非表示にしてテキストボックスを完全に読み取り専用にする必要がある場合は表示します。
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;
}
}
}
}
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プロパティ...
ReadOnly Comboの最適なソリューションは次のとおりです。
private void combo1_KeyPress(object sender, KeyPressEventArgs e)
{
e.KeyChar = (char)Keys.None;
}
コンボのキー押下は破棄されます。
前景色と背景色を有効なコンボボックスのシステムカラーに変更できますが、これによりユーザーが混乱する可能性があります(変更できない場合にそれを使用する理由)、見た目が良くなります。
これは、Enabled = False
を含むComboBox
が読みにくいという事実に対処する方法です。
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;
}
すでにデータを入力し、適切なアイテムを選択してDropDownList
にした場合、次のような拡張メソッドを使用して、選択リストを選択したアイテムだけにすばやく縮小できます。
public static void MakeReadOnly(this ComboBox pComboBox) {
if (pComboBox.SelectedItem == null)
return;
pComboBox.DataSource = new List<object> {
pComboBox.SelectedItem
};
}
コードの最も簡単な方法:
KeyPress
またはKeyDown
のメソッドを追加する代わりに、 '_Form1_Load
_'メソッドに次のコードを追加します。
comboBox1.KeyPress += (sndr, eva) => eva.Handled = true;
または
comboBox1.KeyDown += (sndr, eva) => eva.SuppressKeyPress = true;
_(sndr, eva)
_は_(object sender, EventArgs e)
_用です
私はパーティーに少し遅れていることを知っていますが、この正確な質問を調査していたので、コンボボックスをテキストボックスのように読み取り専用にし、リストがポップアップするのを無効にする方法が必要であることがわかりました。それは完璧ではありませんが、インターネット上で見つけたすべての答えよりも、私にとってはうまくいかないことは間違いありません。ボタンが押されて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);
}
}
}
実際、かなり単純です:
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
テキストボックスを使用しないのはなぜですか。テキストボックスには "読み取り専用"プロパティがあり、コンボボックスにデータのみを表示するため、コンボボックスが必要な理由がわかりません。
別の方法は、「on value changed」イベントの入力をキャンセルするだけです。そうすれば、ユーザーが何をするかに関わらず、情報を表示できます...