Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Lekim en 28 Octubre 2015, 19:33 pm



Título: ComboBox que no despliegue la lista al hacer click sobre el cuadro de text (WPF)
Publicado por: Lekim en 28 Octubre 2015, 19:33 pm
Hola

Pues eso, ayer estuve más de una hora cambiando esto y aquello para evitar que al hacer clic sobre el ComboBox NO despliegue la lista pero SI que lo haga la pulsar el botón.

Si el ComboBox no está personalizado, es decir, que no le hemos aplicado ningún estilo, basta con cambiar la propiedad IsEditable a True

Código
  1. <ComboBox Name="ComboBox1" IsEditable="True"  Height="25" Width="150" Margin="0,20,0,0"> </ComboBox>

Pero cuando se le aplica un estilo no hay forma de conseguir que no despliegue la lista al hacer clic sobre él.

Aquí dejo un enlace con un ejemplo de estilo para el ComboBox
ComboBox ControlTemplate Example (https://msdn.microsoft.com/en-us/library/ms752094(v=vs.85).aspx)

Si establezco IsEditable= "True" se puede editar pero al hacer clic sobre el cuadro de texto para editarlo se despliega la lista.

Gracias



Título: Re: ComboBox que no despliegue la lista al hacer click sobre el cuadro de text (WPF)
Publicado por: Lekim en 17 Noviembre 2015, 17:50 pm
 :o ¿En serio? ¿Nadie contesta?

En fin no me extraña. Parece como si nadie programara con WPF en código VB. Cada vez que busco en Google, casi todo es C#.

Pero no importa porque encontré la solución a base de analizar paso por paso el código XAML del estilo del Combobox. Sin embargo hay un problema, de la solución se deriva un nuevo problema que no creo que pueda resolver y que si nadie contesta plantearé en una nueva pregunta.

LA SOLUCIÓN:
Lo primero es aplicar la propiedad  IsEditable="True"

Código
  1. < <ComboBox  Name="ComboBox1"  Height="23" IsEditable="True" HorizontalAlignment="Left" Margin="35,31,0,0" VerticalAlignment="Top" Width="192" />

También se puede aplicar esta propiedad para todos los ComboBox en nuestro estilo ComboBox en código XAML del ResourceDictionary :

Código
  1.  <Setter Property="IsEditable" Value="True" />

Dentro del estilo Combobox...:
      
Código
  1. <Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
  2.            <Setter Property="SnapsToDevicePixels" Value="true"/>
  3.            <Setter Property="OverridesDefaultStyle" Value="true"/>
  4.            <Setter Property="IsEditable" Value="True" />
  5.            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
  6.            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
  7.            <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
  8.            <Setter Property="MinWidth" Value="120"/>
  9. ....

Hecho esto el ComboBox es editable, sí, pero ocurre lo siguiente. Si hacemos click en el combo para escribir en él se despliega la lista del combo, esté lleno o no:

(http://3.bp.blogspot.com/-D93IOAdKRCM/VktY5YkNeAI/AAAAAAAAATg/dnkuFxfvSUc/s1600/click_lista.gif)


Esto ocurre porque el ComboBox se compone de capas una sobre otra y la capa TextBox tiene el valor de la propiedad Width nulo. El número de  capas depende del estilo. En el  link que puse arriba está el ToggleButton que es el botón, y encima de él está el TextBox (la caja de texto). Hay muchos estilos colgados en la red para este control y todos coinciden en no establecer el Width para la caja de texto, luego su valor es 0. De modo que cuando haces click sobre cualquier parte del ComboBox es como si presionaras el botón. El valor del Width de la caja de texto crece a medida que se escribe.

Entonces solo hay que establecer el Width del TexBox del Combo. El valor debe ser igual al ancho (Width) del Combo. El ancho del combo no incluye el botón gráfico, por lo que el ancho del TexBox se detendrá justo antes de llegar al botón gráfico.

Esto lo haces en el estilo del ResourceDictionary:

(observa Width="192")
Código
  1. ....
  2. <TextBox x:Name="PART_EditableTextBox"
  3.            Style="{x:Null}"
  4.            Template="{StaticResource ComboBoxTextBox}"
  5.            HorizontalAlignment="Left"
  6.            VerticalAlignment="Center"
  7.            Width="192"
  8.            Margin="3,3,23,3"
  9.            Focusable="True"
  10.            Background="Transparent"
  11.            Visibility="Hidden"
  12.            IsReadOnly="{TemplateBinding IsReadOnly}"/>
  13. ....
  14.  

Ahora el TexBox no tiene valor nulo y cuando hagas click en el Combo se activará la caja de texto para escribir, y no se desplegará la lista, puesto que has hecho click en la caja de texto y no en el botón.

(http://2.bp.blogspot.com/-qY36sxvAKT4/VktY5WtnAKI/AAAAAAAAATo/5Kwcu6NQP9k/s1600/click_Edit.gif)

Sin embargo hay un problema, si sigues escribiendo el width de la caja de texto no para de crecer superando incluso el botón gráfico, lo cual no queda bien. No es nada presentable. Podemos establecer el MaxLength= X pero ¿Que pasa si queremos meter una dirección URL cuyo número de carácteres supera el MaxLength? pues que no podremos meterlo. Entonces no nos sirve:

(http://4.bp.blogspot.com/-a5P-cqnDAbo/VktY4yRh4tI/AAAAAAAAATk/g64YdfH30KM/s320/WriteAndSelect.gif)

Espero que alguien pueda solucionarme este último problema. No se si hay una propiedad para establecer el límite (y que no sea MaxLength pues no sirve)

Saludos