it-swarm.com.de

Wie wird Text in einem Kombinationsfeld angezeigt, wenn kein Element ausgewählt ist?

C # & .Net 2.0-Frage (WinForms)

Ich habe Artikel in ComboBox gesetzt und keine davon ausgewählt. Ich möchte eine Zeichenfolge in der Combo " Bitte in dieser Situation auswählen " anzeigen. 

Bei der aktuellen Implementierung wird lediglich ein leeres Element mit einem solchen Text im Index 0 hinzugefügt und entfernt, wenn der Benutzer eines der folgenden Elemente auswählt. Leider wird auch ein leerer Artikel in der Dropdown-Liste angezeigt. So vermeiden Sie diese Situation oder auf andere Weise - gibt es eine Möglichkeit, benutzerdefinierten Text in ComboBox anzuzeigen, wenn kein Element ausgewählt ist?

Die folgenden Antworten funktionieren, wenn ComboBoxStyle auf DropDown gesetzt ist (ComboBox ist editierbar). Gibt es die Möglichkeit, dies zu tun, wenn ComboBoxStyle auf DropDownList gesetzt ist?

20
jotbek

Hier finden Sie eine Lösung, die von pavlo_ua erstellt wurde: Wenn Sie .Net> 2.0 und haben. Wenn Sie .Net == 2.0 haben (Suche nach pavlo_ua Antwort)

Prost, jbk

edit: Um eine klare Antwort zu erhalten, nicht nur einen Link

Sie können den Text der Combobox festlegen, wenn der Stil als DropDown (und bearbeitbar) definiert ist .. Wenn Sie die .NET-Version <3.0 haben, gibt es keine IsReadonly-Eigenschaft :

private bool m_readOnly = false;
private const int EM_SETREADONLY = 0x00CF;

internal delegate bool EnumChildWindowsCallBack( IntPtr hwnd, IntPtr lParam );

[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

[ DllImport( "user32.dll" ) ]
internal static extern int EnumChildWindows( IntPtr hWndParent, EnumChildWindowsCallBack lpEnumFunc, IntPtr lParam );


private bool EnumChildWindowsCallBackFunction(IntPtr hWnd, IntPtr lparam)
{
      if( hWnd != IntPtr.Zero )
       {
              IntPtr readonlyValue = ( m_readOnly ) ? new IntPtr( 1 ) : IntPtr.Zero;
             SendMessage( hWnd, EM_SETREADONLY, readonlyValue, IntPtr.Zero );
             comboBox1.Invalidate();
             return true;
       }
       return false;
}

private void MakeComboBoxReadOnly( bool readOnly )
{
    m_readOnly = readOnly;
    EnumChildWindowsCallBack callBack = new EnumChildWindowsCallBack(this.EnumChildWindowsCallBackFunction );
    EnumChildWindows( comboBox1.Handle, callBack, IntPtr.Zero );
}
0
jotbek

Verwenden Sie die Einfügemethode der Combobox, um den "Bitte Artikel auswählen" in den 0-Index einzufügen. 

comboBox1.Items.Insert(0, "Please select any value");

und fügen Sie alle Elemente nach dem ersten Index der Combobox hinzu. Im Formularladesatz 

comboBox1.SelectedIndex = 0;

BEARBEITEN:

Beim Laden des Formulars schreiben Sie den Text durch Hardcoding in den comboBox1.Text

comboBox1.Text = "Please, select any value";

und schreiben Sie in dem TextChanged-Ereignis der comboBox1 den folgenden Code

 private void comboBox1_TextChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex < 0)
            {
                comboBox1.Text = "Please, select any value";
            }
            else
            {
                comboBox1.Text = comboBox1.SelectedText;
            }
        }

So mache ich es. Es ist möglicherweise nicht die beste Methode und bietet die geringste Kontrolle. Es ist jedoch einfach und schnell und ich dachte, es wäre eine gute Idee, es weiterzugeben, damit andere Optionen zur Verfügung stehen.

<ComboBox SelectedIndex="0">
    <ComboBoxItem Visibility="Collapsed">Please select one...</ComboBoxItem>
    <ComboBoxItem>1</ComboBoxItem>
    <ComboBoxItem>2</ComboBoxItem>
    <ComboBoxItem>3</ComboBoxItem>
    <ComboBoxItem>4</ComboBoxItem>
</ComboBox>

Die Idee dahinter ist, dass die anfängliche Auswahl der Index 0 ist, der reduziert ist, sodass sie nicht für den Benutzer verfügbar ist, sobald sie etwas anderes auswählen. Der Nachteil ist, dass Sie bei der Suche nach einem ausgewählten Index bedenken müssen, dass Index 0 bedeutet, dass keine Auswahl getroffen wurde.

5
B.K.
    private void comboBox1_TextChanged(object sender, EventArgs e)
    {
        if (comboBox1.Text == "")
            comboBox1.Text = "Select one of the answers"; 
    }

wenn der Trick ausgeführt werden sollat ist diese Zeile vorhanden. Wenn Sie ein Element in der Combobox auswählen, wird dieser Text angezeigt. Beim Löschen des Textes erscheint dieser Text erneut

3
Moonlight

Ich habe eine schnelle Umgehung vorgenommen, um den DropDownList-Stil beibehalten zu können.

class DummyComboBoxItem
{
    public string DisplayName
    {
        get
        {
            return "Make a selection ...";
        }
    }
}
public partial class mainForm : Form
{
    private DummyComboBoxItem placeholder = new DummyComboBoxItem();
    public mainForm()
    {
        InitializeComponent();

        myComboBox.DisplayMember = "DisplayName";            
        myComboBox.Items.Add(placeholder);
        foreach(object o in Objects)
        {
            myComboBox.Items.Add(o);
        }
        myComboBox.SelectedItem = placeholder;
    }

    private void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (myComboBox.SelectedItem == null) return;
        if (myComboBox.SelectedItem == placeholder) return;            
        /*
            do your stuff
        */
        myComboBox.Items.Add(placeholder);
        myComboBox.SelectedItem = placeholder;
    }

    private void myComboBox_DropDown(object sender, EventArgs e)
    {
        myComboBox.Items.Remove(placeholder);
    }

    private void myComboBox_Leave(object sender, EventArgs e)
    {
        //this covers user aborting the selection (by clicking away or choosing the system null drop down option)
        //The control may not immedietly change, but if the user clicks anywhere else it will reset
        if(myComboBox.SelectedItem != placeholder)
        {
            if(!myComboBox.Items.Contains(placeholder)) myComboBox.Items.Add(placeholder);
            myComboBox.SelectedItem = placeholder;
        }            
    }       
}

Wenn Sie Datenbindung verwenden, müssen Sie eine Dummy-Version des Typs erstellen, an den Sie gebunden sind. Stellen Sie sicher, dass Sie sie vor jeder Persistenzlogik entfernen.

2
Jesse Adam

Eine Zeile nach dem Formular InitializeComponent();

cbo_MyDropBox.Text = "Select a server...";

Sie brauchen es nur einmal richtig? Wenn eine Auswahl obligatorisch ist, müssen Sie nur prüfen, ob das Kästchen Index != -1 ist. Könnte jemand etwas näher erläutern, warum die anderen Antworten durch Reifen springen, um dies in Gang zu setzen? 

Das einzige, was mir fehlt, ist, dass dieser erste Text ausgegraut ist. Wenn Sie das wirklich wollen, verwenden Sie einfach ein Label vor und deaktivieren Sie es, sobald der Index geändert wird.

1
Madmenyo

Machen Sie die Dropdownstyle-Eigenschaft des Kombinationsfelds zu Dropdown und setzen Sie den Kombinationsfeld-Text wie folgt auf "Auswählen" 

            combobox.DataSource = dsIn.Tables[0];
            combobox.DisplayMember = "Name";
            combobox.ValueMember = "Value";
            combobox.Text = "--Select--";
1
prema

Ich kann keine native .NET-Methode dafür erkennen, aber wenn Sie Ihre Hände mit den zugrunde liegenden Win32-Steuerelementen verschmutzen möchten ...

Sie sollten in der Lage sein, die CB_GETCOMBOBOXINFO-Nachricht mit einer COMBOBOXINFO-Struktur zu senden, die das Handle des internen Editiersteuerelements enthalten soll ..__ Sie können dann die EM_SETCUEBANNER-Nachricht mit einem Zeiger auf die Zeichenfolge . Senden Es müssen mindestens XP und visuelle Stile aktiviert sein.

1
Deanna

wenn ComboBoxStyle auf DropDownList eingestellt ist, können Sie am einfachsten sicherstellen, dass der Benutzer ein Element auswählt, indem Sie SelectedIndex = -1 setzen. Dieser ist leer

0
Harry

Dies funktioniert mit dem DropDownList-Stil. Erstellen Sie eine von ComboBox abgeleitete Klasse
(wird nach dem Neuaufbau in Toolbox angezeigt), wodurch der Hinweis mithilfe von System.Drawing gezeichnet wird.
Platzieren Sie dieses Steuerelement aus der Toolbox in Ihr Formular und setzen Sie in den Eigenschaften den Hinweis "Bitte Element auswählen".

public class HintComboBox : ComboBox
{
    string hint;
    public string Hint
    {
        get { return hint; }
        set { hint = value; Invalidate(); }
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == 0xf && !Focused && string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(Hint))
           using (var g = CreateGraphics())
           {
               TextRenderer.DrawText(g, Hint, Font, ClientRectangle, SystemColors.GrayText, BackColor,
                                    TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter);
           }
    }
}
0

Ich weiß, dass dies ein alter Thread ist, aber ich wollte nur andere, die nach einer Antwort auf diese Frage suchen, wissen lassen. In der aktuellen Version von Visual Studio (2015) gibt es eine Eigenschaft namens "Placeholder Text", die jotbek ursprünglich tut fragte nach. Verwenden Sie das Feld Eigenschaften unter "Allgemeine" Eigenschaften.

0
wheezer

Wenn keine der vorherigen Lösungen für Sie funktioniert, fügen Sie eine Prüfung in der Combobox ein 

    var orginalindex = 0;

    private void comboBox1_SelectedItemChanged(object sender, EventArgs e)
    {
        if (comboBox1.SelectedIndex == 0)
        {
            comboBox1.Text = "Select one of the answers";
            comboBox1.SelectedIndex = comboBox1.SelectedIndex;
        }
        else
        {
            orginalindex = comboBox1.SelectedIndex;
        }
    }
0
Ash Burlaczenko

Ich hatte gehofft, auch dafür eine Lösung zu finden. Ich sehe, dass dies ein älterer Beitrag ist, aber ich hoffe, mein Ansatz könnte dieses Problem für jemand anderen vereinfachen.

Ich habe eine Combobox mit einem Dropdown-Stil von DropDownList verwendet, dies sollte jedoch mit anderen Stilen funktionieren. In meinem Fall wollte ich, dass der Text "Quelle auswählen" lautet, und ich wollte, dass die anderen Optionen "Datei" und "Ordner" sind.

comboBox1.Items.AddRange(new string[] {"Select Source", "File", "Folder" });
comboBox1.Text = "Select Source";

Wenn Sie möchten, können Sie stattdessen den Index 0 auswählen. Ich entfernte dann das Element "Quelle auswählen", wenn der Index geändert wird, da es nicht mehr wichtig ist, wenn der Text sichtbar ist.

comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_IndexChanged);

private void comboBox1_IndexChanged(object sender, EventArgs e)
    {
        comboBox1.Items.Remove("Select Source");
        if (comboBox1.SelectedIndex != -1)
        {
            if (comboBox1.SelectedIndex == 0) // File
            {
                // Do things
            }
            else if (comboBox1.SelectedIndex == 1) // Folder
            {
                // Do things
            }
        }
    }

Vielen Dank

0
NAPTlME

Der Ansatz von @Andrei Karcheuski konnte nicht erreicht werden, aber er inspirierte mich zu diesem Ansatz: (Ich habe die Localizable-Eigenschaft hinzugefügt, sodass der Hinweis durch die .resx-Dateien für jeden Dialog übersetzt werden kann, in dem Sie ihn verwenden.)

 public partial class HintComboBox : ComboBox
{
    string hint;
    Font greyFont;

    [Localizable(true)]
    public string Hint
    {
        get { return hint; }
        set { hint = value; Invalidate(); }
    }

    public HintComboBox()
    {
        InitializeComponent();
    }

    protected override void OnCreateControl()
    {
        base.OnCreateControl();

        if (string.IsNullOrEmpty(Text))
        {
            this.ForeColor = SystemColors.GrayText;
            Text = Hint;
        }
        else
        {
            this.ForeColor = Color.Black;
        }
    }

    private void HintComboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if( string.IsNullOrEmpty(Text) )
        {
            this.ForeColor = SystemColors.GrayText;
            Text = Hint;
        }
        else
        {
            this.ForeColor = Color.Black;
        }
    }
0
wecky

Leider funktionierte keiner der oben genannten Punkte für mich. Stattdessen fügte ich oben auf der Comboxbox ein Etikett hinzu, auf dem "Bitte auswählen" steht. Ich habe den folgenden Code verwendet, um ihn ein- und auszublenden:

  1. Wenn ich meine Combobox initialisiere, wenn kein ausgewählter Wert vorhanden ist, bringe ich sie nach vorne und setze den Text:

    PleaseSelectValueLabel.BringToFront();
    PleaseSelectValueLabel.Text = Constants.AssessmentValuePrompt;
    
  2. Wenn ein Wert ausgewählt ist, sende ich ihn nach hinten:

    PleaseSelectValueLabel.SendToBack();
    
  3. Ich verwende dann die folgenden Ereignisse, um die Beschriftung nach vorne oder nach hinten zu verschieben, je nachdem, ob der Benutzer einen Wert ausgewählt hat:

    private void PleaseSelectValueLabel_Click(object sender, EventArgs e)
    {
        PleaseSelectValueLabel.SendToBack();
        AssessmentValue.Focus();
    }
    
    private void AssessmentValue_Click(object sender, EventArgs e)
    {
        PleaseSelectValueLabel.SendToBack();
    }
    
    //if the user hasnt selected an item, make the please select label visible again
    private void AssessmentValue_Leave(object sender, EventArgs e)
    {
        if (AssessmentValue.SelectedIndex < 0)
        {
            PleaseSelectValueLabel.BringToFront();
        }
    }
    
0
majjam