2011-11-09 10 views
15

C# .Net 2.0 & pregunta (WinForms)¿Cómo mostrar texto en el cuadro combinado cuando no se seleccionó ningún elemento?

He conjunto de elementos de ComboBox y no de ellos seleccionado. Me gustaría mostrar una cadena en el combo "Seleccione el elemento" en esa situación.

La implementación actual se acaba de agregar elemento vacío con dicho texto en el índice y eliminarlo cuando el usuario seleccione uno de los siguientes elementos. Lamentablemente, el artículo vacío también se muestra en la lista desplegable. Cómo evitar esta situación o de otra manera: ¿hay alguna manera de mostrar texto personalizado en ComboBox cuando no se selecciona ningún elemento?

Las respuestas a continuación trabajan cuando ComboBoxStyle se establece en DropDown (ComboBox es editable). ¿Hay posibilidad de hacer esto cuando ComboBoxStyle se establece en DropDownList?

+0

.... así que cuando el usuario seleccione el elemento en el cuadro combinado que no desea mostrar el texto de encargo en los artículos ... – rockyashkumar

+0

Tome un vistazo a http://stackoverflow.com/ questions/1426050/how-to-display-default-text-select-team-in-combo-box-on-pageload-in-wpf – PaulB

+0

Estoy buscando una solución que funcione con WinForms y no con WPF. Para ser estrictamente, edité la primera publicación y lo subrayé. Gracias. – jotbek

Respuesta

0

Aquí puede encontrar solución creada por pavlo_ua: If you have .Net > 2.0 y If you have .Net == 2.0 (search for pavlo_ua answer)

Cheers, jbk

edición: Así que para tener una respuesta clara no sólo enlazar

Es posible ajustar texto del cuadro combinado cuando su estilo está configurado como DropDown (y es editable). Cuando se tiene la versión 3.0 .Net < no hay ninguna propiedad IsReadOnly por lo que tenemos que utilizar la API de ganar para establecer cuadro de texto del cuadro combinado como de sólo lectura:

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

Si bien esto podría responder teóricamente a la pregunta, [sería preferible] (http://meta.stackexchange.com/q/8259) incluir aquí las partes esenciales de la respuesta y proporcionar el enlace de referencia. – codingbadger

+0

puede usar e.Handled = true en el evento de presionar teclas del cuadro combinado para evitar que el usuario cambie el texto en el modo desplegable – Arash

12

utilizar el método de inserción del cuadro combinado de insertar el "Por favor, seleccionar el elemento" a 0 índice,

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

y añadir todos los elementos para el cuadro combinado después de que el primer índice. En la carga del conjunto de formularios

comboBox1.SelectedIndex = 0; 

EDIT:

en carga del formulario escribir el texto en el comboBox1.Text hardcoding

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

y en el caso TextChanged del comboBox1 escribir el siguiente código

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

Pero eso significaría que el usuario puede seleccionar esto. Supongo que el usuario quiere que esto se muestre como una pista y no como una respuesta seleccionable. – RvdK

+1

Sí, es mi implementación actual, pero este elemento se muestra en la lista desplegable y el usuario aún puede elegirlo. Me gustaría evitar esa situación y mostrar texto solo en el cuadro combinado pero no en la lista desplegable. – jotbek

+0

@jotbek, ver mi publicación editada –

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

debe hacer el truco al inicio esta línea está presente, cuando se selecciona un elemento en el cuadro combinado, aparecerá el texto de estos elementos. cuando deleling el texto este texto aparecerá de nuevo

+0

Por alguna razón, simplemente no funciona. Esta solución es una que todos sugieren aquí, pero cuando establezco la propiedad Text no se conserva el valor pasado. Tal vez el método ToString de los elementos en la colección tiene prioridad sobre la propiedad Text. – jotbek

+1

Funciona solo cuando se establece DropDown of ComboBoxStyle. – jotbek

+0

funciona para el menú desplegable y el estilo simple, DropdownList no funciona. – Moonlight

0

Si ninguna de la solución anterior están trabajando para usted, por qué no añadir una validación de cuadro combinado algo como,

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

Opción 0 significa la primera entrada en el cuadro combinado. Yo usaría -1, lo que significa que no se seleccionó ningún elemento. – HelpNeeder

1

hacer que la propiedad DropDownStyle del cuadro combinado para desplegable y establecer el texto de cuadro combinado a "Seleccionar" de la siguiente manera

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

no puedo ver ninguna manera .NET nativo para hacerlo, pero si usted desea conseguir sus manos sucias con la subyacente controla Win32 ...

Debería poder enviarle el mensaje CB_GETCOMBOBOXINFO con una estructura COMBOBOXINFO que contendrá el control del editor interno. A continuación, puede enviar el control de edición al mensaje EM_SETCUEBANNER con un puntero a la cadena. (Tenga en cuenta que esto requiere al menos XP y estilos visuales para ser habilitados.

+0

Sí, estoy de acuerdo, aquí tiene la solución para .Net 2.0: [enlace] http://social.msdn.microsoft.com/Forums/en/winformsdesigner/thread/0004035e-4f1d-4b16-bd97-6123c209fe2f búsqueda de solución pavlo_ua – jotbek

0

si ComboBoxStyle se establece en DropDownList entonces la forma más fácil de asegurarse de que la El usuario selecciona un elemento para establecer SelectedIndex = -1, que estará vacío

3

Así es como lo hago. Puede que no sea el mejor método y ofrece menos control; sin embargo, es simple y rápido y pensé que sería una buena idea compartirlo para que haya más opciones disponibles para otros.

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

La idea detrás de esto es que la selección inicial es el índice 0, que se derrumbó, por lo que no está disponible en virtud de selección para el usuario una vez que se seleccione otra cosa. La desventaja es que debe recordar que si está buscando un índice seleccionado, recuerde que el índice 0 significa que no se realizó ninguna selección.

+1

Excelente respuesta. La selección inicial desaparece después de la primera selección y no aparece en la lista desplegable. Excelente solución rápida. – pollaris

-2

¿Por qué no hacerlo XAML?

<ComboBox x:Name="myComboBoxMenu" PlaceholderText="Hello"/> 
+5

Porque es Winforms ... –

+0

esto no es válido en XAML –

0

Soy consciente de que es un viejo hilo, pero sólo quería que otras personas que podrían buscar una respuesta a esta pregunta saber, en la versión actual de Visual Studio (2015), hay una propiedad llamada "marcador de posición Texto "que hace lo que Jotbek originalmente preguntó. Use el cuadro Propiedades, bajo propiedades "Comunes".

+1

Eso suena bien pero no veo esa propiedad en 'ComboBox' en https://msdn.microsoft.com/en-us/library/system.windows .forms.combobox (v = vs.110) .aspx – user276648

1

Utilicé un trabajo rápido para poder mantener el estilo DropDownList.

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; 
     }    
    }  
} 

Si utiliza el enlace de datos que tendrá que crear una versión ficticia del tipo que está obligado a - sólo asegúrese de eliminar antes de cualquier lógica de persistencia.

1

Una línea después de forma InitializeComponent();

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

Sólo se necesitan una vez ¿verdad? Todo lo que necesita hacer si una selección es obligatoria es verificar si el índice de caja != -1. ¿Podría alguien explicar por qué las otras respuestas saltan a través de aros para que esto suceda?

Lo único que me falta aquí es tener este texto inicial en gris. Si realmente quiere eso, simplemente use una etiqueta en el frente y apáguela una vez que se cambie el índice.

0

Lamentablemente ninguno de los anteriores funcionó para mí, así que en su lugar agregué una etiqueta en la parte superior de la caja de combox que dice "Seleccione".He utilizado el código siguiente para mostrar y ocultar:

  1. Cuando inicializar mi cuadro combinado, si no hay valor seleccionado que llevarlo a la parte delantera y establecer el texto:

    PleaseSelectValueLabel.BringToFront(); 
    PleaseSelectValueLabel.Text = Constants.AssessmentValuePrompt; 
    
  2. Si hay un valor seleccionado lo envío a la parte posterior:

    PleaseSelectValueLabel.SendToBack(); 
    
  3. entonces utilizo los siguientes eventos para mover la etiqueta a la parte delantera o trasera dependiendo de si el usuario ha seleccionado un Valu e:

    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

Tenía la esperanza de encontrar una solución a este también. Veo que esta es una publicación más antigua, pero espero que mi enfoque pueda simplificar este problema para otra persona.

Estaba usando un cuadro combinado con un estilo desplegable de DropDownList, pero esto debería funcionar con otros estilos. En mi caso yo quería que el texto para leer "Seleccionar Fuente" y quería que las otras opciones para ser "Archivo" y "Carpeta"

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

Puede seleccionar el índice 0 en lugar si lo desea. Luego eliminé el elemento "Seleccionar fuente" cuando se modificó el índice, ya que no importa si ese texto está visible.

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 
      } 
     } 
    } 

Gracias

Cuestiones relacionadas