Buscar..


Observaciones

Tenga en cuenta que un UserControl es muy diferente de un Control. Una de las principales diferencias es que un UserControl hace uso de un archivo de diseño XAML para determinar dónde colocar varios controles individuales. Un control, por otro lado, es solo código puro, no hay ningún archivo de diseño. De alguna manera, crear un Control personalizado puede ser más efectivo que crear un UserControl personalizado.

ComboBox con texto predeterminado personalizado

Este UserControl personalizado aparecerá como un cuadro combinado regular, pero a diferencia del objeto ComboBox incorporado, puede mostrar al usuario una cadena de texto predeterminada si aún no ha realizado una selección.

Para lograr esto, nuestro UserControl estará compuesto por dos controles. Obviamente necesitamos un ComboBox real, pero también usaremos una etiqueta regular para mostrar el texto predeterminado.


CustomComboBox.xaml

<UserControl x:Class="UserControlDemo.CustomComboBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:cnvrt="clr-namespace:UserControlDemo"
             x:Name="customComboBox">
    <UserControl.Resources>
        <cnvrt:InverseNullVisibilityConverter x:Key="invNullVisibleConverter" />
    </UserControl.Resources>
    <Grid>
        <ComboBox x:Name="comboBox"
                  ItemsSource="{Binding ElementName=customComboBox, Path=MyItemsSource}"
                  SelectedItem="{Binding ElementName=customComboBox, Path=MySelectedItem}"
                  HorizontalContentAlignment="Left" VerticalContentAlignment="Center"/>
        
        <Label HorizontalAlignment="Left" VerticalAlignment="Center"
               Margin="0,2,20,2" IsHitTestVisible="False"
               Content="{Binding ElementName=customComboBox, Path=DefaultText}"
               Visibility="{Binding ElementName=comboBox, Path=SelectedItem, Converter={StaticResource invNullVisibleConverter}}"/>
    </Grid>
</UserControl>

Como puede ver, este único UserControl es en realidad un grupo de dos controles individuales. Esto nos permite cierta flexibilidad que no está disponible en un solo ComboBox solo.

Aquí hay varias cosas importantes a tener en cuenta:

  • El UserControl en sí tiene un x:Name establecido. Esto se debe a que queremos vincularnos a las propiedades que se encuentran en el código subyacente, lo que significa que necesita alguna forma de referenciarse a sí mismo.
  • Cada uno de los enlaces en el ComboBox tiene el nombre de UserControl como ElementName . Esto es para que el UserControl sepa mirarse a sí mismo para localizar los enlaces.
  • La etiqueta no es visible. Esto es para dar al usuario la ilusión de que la etiqueta es parte de ComboBox. Al establecer IsHitTestVisible=false , no permitimos que el usuario se IsHitTestVisible=false o haga clic en la etiqueta: todas las entradas se pasan a través del ComboBox a continuación.
  • La etiqueta utiliza un convertidor de InverseNullVisibility para determinar si debe mostrarse o no. Puede encontrar el código para esto al final de este ejemplo.

CustomComboBox.xaml.cs

public partial class CustomComboBox : UserControl
{
    public CustomComboBox()
    {
        InitializeComponent();
    }

    public static DependencyProperty DefaultTextProperty =
        DependencyProperty.Register("DefaultText", typeof(string), typeof(CustomComboBox));

    public static DependencyProperty MyItemsSourceProperty = 
        DependencyProperty.Register("MyItemsSource", typeof(IEnumerable), typeof(CustomComboBox));

    public static DependencyProperty SelectedItemProperty =
        DependencyProperty.Register("SelectedItem", typeof(object), typeof(CustomComboBox));

    public string DefaultText
    {
        get { return (string)GetValue(DefaultTextProperty); }
        set { SetValue(DefaultTextProperty, value); }
    }

    public IEnumerable MyItemsSource
    {
        get { return (IEnumerable)GetValue(MyItemsSourceProperty); }
        set { SetValue(MyItemsSourceProperty, value); }
    }

    public object MySelectedItem
    {
        get { return GetValue(MySelectedItemProperty); }
        set { SetValue(MySelectedItemProperty, value); }
    }
}

En el código subyacente, simplemente estamos exponiendo qué propiedades queremos que estén disponibles para el programador utilizando este UserControl. Desafortunadamente, debido a que no tenemos acceso directo a la ComboBox desde fuera de esta clase, que necesitamos para mostrar las propiedades duplicadas ( MyItemsSource para el cuadro combinado de ItemsSource , por ejemplo). Sin embargo, esta es una compensación menor considerando que ahora podemos usar esto de manera similar a un control nativo.


Aquí es cómo se puede utilizar el CustomComboBox :

<Window x:Class="UserControlDemo.UserControlDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cntrls="clr-namespace:UserControlDemo"
        Title="UserControlDemo" Height="240" Width=200>
    <Grid>
        <cntrls:CustomComboBox HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="165"
                               MyItemsSource="{Binding Options}"
                               MySelectedItem="{Binding SelectedOption, Mode=TwoWay}"
                               DefaultText="Select an option..."/>
    <Grid>
</Window>

Y el resultado final:

Figura 1 introduzca la descripción de la imagen aquí figura 3


Aquí está el InverseNullVisibilityConverter necesario para la etiqueta en el UserControl, que es solo una pequeña variación en la versión de lll :

public class InverseNullVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Visible : Visibility.Hidden;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow