Recherche…


Remarques

Notez qu'un UserControl est très différent d'un contrôle. L'une des principales différences est qu'un UserControl utilise un fichier de disposition XAML pour déterminer où placer plusieurs contrôles individuels. Un contrôle, par contre, est un code pur - il n'y a aucun fichier de mise en page. À certains égards, la création d'un contrôle personnalisé peut être plus efficace que la création d'un contrôle utilisateur personnalisé.

ComboBox avec un texte par défaut personnalisé

Cet UserControl personnalisé apparaîtra comme une liste déroulante standard, mais contrairement à l'objet ComboBox intégré, il peut afficher une chaîne de texte par défaut s'il n'a pas encore été sélectionné.

Pour ce faire, notre UserControl sera composé de deux contrôles. Nous avons évidemment besoin d'une ComboBox réelle, mais nous utiliserons également une étiquette régulière pour afficher le texte par défaut.


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>

Comme vous pouvez le voir, ce seul UserControl est en réalité un groupe de deux contrôles individuels. Cela nous permet une certaine flexibilité qui n'est pas disponible dans une seule zone de liste déroulante.

Voici plusieurs points importants à noter:

  • Le UserControl lui-même a un ensemble x:Name . Cela est dû au fait que nous souhaitons lier des propriétés situées dans le code-behind, ce qui signifie qu’il a besoin de se référencer.
  • Chaque liaison de la zone de liste déroulante porte le nom de UserControl en tant que nom d' ElementName . Cela permet à UserControl de se regarder pour localiser les liaisons.
  • L'étiquette n'est pas visible pour le test de réussite. Cela donne à l'utilisateur l'illusion que le Label fait partie de la ComboBox. En définissant IsHitTestVisible=false , nous interdisons à l’utilisateur de survoler ou de cliquer sur l’étiquette - toutes les entrées sont transmises à la zone de liste déroulante ci-dessous.
  • Le Label utilise un convertisseur InverseNullVisibility pour déterminer s'il doit ou non s'afficher. Vous pouvez trouver le code pour cela au bas de cet exemple.

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

Dans le code-behind, nous exposons simplement les propriétés que nous voulons mettre à la disposition du programmeur en utilisant ce UserControl. Malheureusement, comme nous n’avons pas d’accès direct au ComboBox en dehors de cette classe, nous devons exposer les propriétés en double ( MyItemsSource pour ItemsSource de ComboBox, par exemple). Cependant, ceci est un compromis mineur étant donné que nous pouvons maintenant utiliser ceci comme un contrôle natif.


Voici comment utiliser le CustomComboBox UserControl:

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

Et le résultat final:

Figure 1 entrer la description de l'image ici figure 3


Voici le InverseNullVisibilityConverter nécessaire pour le Label sur UserControl, qui n'est qu'une légère variation de la version 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow