it-swarm.com.de

Wie man Combobox in Winforms Readonly macht

Ich möchte nicht, dass der Benutzer den in der Combobox angezeigten Wert ändern kann. Ich habe Enabled = false verwendet, aber der Text ist grau, daher ist er nicht sehr gut lesbar. Ich möchte, dass er sich wie ein Textfeld mit ReadOnly = true verhält, wobei der Text normal angezeigt wird, der Benutzer ihn jedoch nicht bearbeiten kann.

Gibt es einen Weg, dies zu erreichen?

50
Kishore A

Der Artikel ComboBox-with-read-only-behaviour schlägt eine interessante Lösung vor:

Erstellen Sie ein Readonly-Textfeld und eine Combobox an derselben Stelle. Wenn Sie den schreibgeschützten Modus wünschen, zeigen Sie das Textfeld an, und wenn Sie möchten, dass es bearbeitet werden kann, zeigen Sie die Combobox an.

18
Joe

machen Sie die DropDownStyle-Eigenschaft in DropDownList anstelle von DropDown Behandeln Sie dann das TextChanged-Ereignis, um zu verhindern, dass der Benutzer den Text ändert.

140
amar vashi

Nicht sicher, ob Sie danach suchen, aber ...

Legen Sie die DropDownStyle = DropDownList fest

Dann zum SelectedIndexChanged-Ereignis

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

Dieser hässliche Teil ist, dass sie sich "fühlen" werden, als könnten sie ihn ändern. Sie denken möglicherweise, dass dies ein Fehler ist, es sei denn, Sie erhalten eine Warnung, in der sie darüber informiert werden, warum sie den Wert nicht ändern können.

10
Dan Williams

Das Beste, was ich vorschlagen kann, ist, das Kombinationsfeld durch ein schreibgeschütztes Textfeld (oder nur ein Etikett) zu ersetzen - so kann der Benutzer den Wert immer noch auswählen/kopieren usw.

Eine andere freche Taktik wäre natürlich, DropDownStyle auf DropDownList zu setzen und einfach alle anderen Optionen zu entfernen - dann hat der Benutzer nichts anderes zu wählen ;-p

8
Marc Gravell

Linkbeschreibung hier eingeben

Ändern Sie einfach die DropDownStyle in DropDownList. Oder wenn Sie möchten, dass nur vollständig gelesen wird, können Sie Enabled = false einstellen. Wenn Ihnen das Aussehen nicht gefällt, habe ich manchmal zwei Steuerelemente, ein Readonly-Textfeld und eine Combobox. Dann blenden Sie die Kombination aus und zeigen das Textfeld an, wenn es vollständig sein soll Readonly und umgekehrt.

7
Virus

Ich habe es durch Unterklasse der ComboBox gehandhabt, um eine ReadOnly-Eigenschaft hinzuzufügen, die sich selbst versteckt, wenn sie gesetzt ist, und oben eine ReadOnly-TextBox mit demselben Text anzeigt:

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

Der Code von Michael R funktioniert, aber ...
Der DropDownHeight = 1; muss auf den Standardwert zurückgesetzt werden, wenn die ReadOnly-Eigenschaft auf false festgelegt ist. Also vor base.OnDropDown(e) einfügen: 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);
        }
    }
}

Um diese Antwort zu vervollständigen:

Datei -> Neu -> Projekt ... Visual C # -> Windows -> Classic Desktop -> Windows Forms-Steuerungsbibliothek

geben Sie den Namen Ihres Steuerelements ein - OK und fügen Sie diesen Code ein. 

Sie können den Namen Ihrer DLL-Datei auswählen:
Projekt - Ihre Projekteigenschaften ... 

  • Assemblyname: Geben Sie den Namen ein. Erstellen Sie einfach die Lösung und Sie haben Ihre DLL-Datei. Öffnen Sie also das Projekt, in dem Sie die schreibgeschützte Kombination verwenden möchten, und klicken Sie mit der rechten Maustaste auf Verweise 
  • Referenz hinzufügen ... und durchsuchen Sie Ihre DLL-Datei. Um Ihre benutzerdefinierte Komponente in Toolbox einzufügen, öffnen Sie Ihre Toolbox, klicken Sie mit der rechten Maustaste auf die Registerkarte Allgemein -> Elemente auswählen ... 
  • Durchsuchen Sie Ihre DLL-Datei - Öffnen Sie. Jetzt können Sie Ihre ReadOnlyComboBox in Ihren Projekten verwenden. PS: Ich verwende VS2015.
2
Fabio

Hier ist die beste Lösung für das ReadOnly Combo.

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

Der Tastendruck für die Kombination wird verworfen.

2
Manish

Sie können den Vorlauf und die Hintergrundfarbe für ein aktiviertes Kombinationsfeld in die Systemfarben ändern. Dies kann jedoch die Benutzer verwirren (warum haben sie es, wenn sie es nicht ändern können).

1
Tom Anderson

So würden Sie die Tatsache angehen, dass eine ComboBox mit Enabled = False schwer zu lesen ist:

Eine Combobox, die anständig aussieht, wenn sie deaktiviert ist

1
Neolisk

Setzen Sie DropdownStyle-Eigenschaft auf Simple.

Fügen Sie den folgenden Code zum KeyPress-Ereignis der ComboBox hinzu

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

Fügen Sie den folgenden Code zum KeyDown-Ereignis der ComboBox hinzu

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

Wenn Sie es bereits ausgefüllt und das entsprechende Element ausgewählt und als DropDownList festgelegt haben, können Sie eine Erweiterungsmethode wie diese verwenden, um die Auswahlliste schnell auf das ausgewählte Element zu reduzieren:

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

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

Einfachster Weg im Code:

anstatt Methoden für KeyPress oder KeyDown hinzuzufügen, fügen Sie diesen Code in die Methode 'Form1_Load' ein:

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

oder

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

(sndr, eva) Steht für (object sender, EventArgs e)

0
snir

Ich weiß, dass ich zu spät zur Party komme, aber ich habe genau nach dieser Frage gesucht und wusste, dass es eine Möglichkeit geben musste, die Combobox so zu lesen, als wäre sie eine Textbox, und die Liste wurde deaktiviert. Es ist nicht perfekt, aber es ist definitiv besser als alle Antworten, die ich im Internet gefunden habe und die für mich nicht funktionieren. Nachdem die Schaltfläche gedrückt wurde und OnDropDown aufgerufen wurde, wird ein neuer Thread erstellt, der die DroppedDown-Eigenschaft auf false setzt, wodurch der Effekt "nichts passiert" entsteht. Das Mausrad wird verbraucht und wichtige Ereignisse werden ebenfalls konsumiert.

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

Eigentlich ist es ziemlich einfach:

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

Warum verwenden Sie nicht einfach ein Textfeld? Das Textfeld hat die Eigenschaft "Nur Lesen". Da Sie möchten, dass Ihr Kombinationsfeld nur Daten anzeigt, kann ich nicht erkennen, warum Sie ein Kombinationsfeld benötigen.

Eine Alternative besteht darin, dass Sie die Eingabe für das Ereignis "Ein Wert geändert" einfach abbrechen. Auf diese Weise werden Sie Ihre Informationen anzeigen, ganz gleich, was der Benutzer tut ...

0
David Božjak