Zoeken…


Opmerkingen

Merk op dat een UserControl heel anders is dan een Control. Een van de belangrijkste verschillen is dat een UserControl gebruik maakt van een XAML-layoutbestand om te bepalen waar verschillende afzonderlijke besturingselementen moeten worden geplaatst. Een besturingselement daarentegen is pure code - er is helemaal geen layoutbestand. In sommige opzichten kan het maken van een aangepast besturingselement effectiever zijn dan het maken van een aangepast UserControl.

ComboBox met aangepaste standaardtekst

Deze aangepaste UserControl zal verschijnen als een normale combobox, maar in tegenstelling tot het ingebouwde ComboBox-object kan het de gebruiker een standaardreeks tekst laten zien als hij nog geen selectie heeft gemaakt.

Om dit te bereiken, bestaat onze UserControl uit twee bedieningselementen. Uiteraard hebben we een echte ComboBox nodig, maar we zullen ook een normaal label gebruiken om de standaardtekst weer te geven.


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>

Zoals u kunt zien, is deze enkele UserControl eigenlijk een groep van twee afzonderlijke bedieningselementen. Dit geeft ons enige flexibiliteit die niet beschikbaar is in een enkele ComboBox alleen.

Hier zijn verschillende belangrijke dingen om op te merken:

  • De UserControl zelf heeft een x:Name set. Dit komt omdat we willen binden aan eigenschappen die zich in de code-behind bevinden, wat betekent dat het een manier nodig heeft om naar zichzelf te verwijzen.
  • Elke binding op de ComboBox heeft de naam UserControl als ElementName . Dit is zodat de UserControl weet naar zichzelf te kijken om bindingen te vinden.
  • Het label is niet zichtbaar. Dit om de gebruiker de illusie te geven dat het label deel uitmaakt van de ComboBox. Door IsHitTestVisible=false , kunnen we de gebruiker niet laten zweven of klikken op het label - alle invoer wordt doorgegeven aan de ComboBox hieronder.
  • Het label gebruikt een InverseNullVisibility omzetter om te bepalen of deze zichzelf moet tonen of niet. U vindt de code hiervoor onderaan dit voorbeeld.

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

In de code achter laten we eenvoudigweg zien welke eigenschappen we beschikbaar willen hebben voor de programmeur met behulp van deze UserControl. Helaas, want we hebben geen directe toegang tot de keuzelijst van buiten deze klasse hebben, moeten we de dubbele eigenschappen (bloot MyItemsSource voor de ComboBox ItemsSource , bijvoorbeeld). Dit is echter een kleine afweging, gezien het feit dat we dit nu op dezelfde manier kunnen gebruiken als een native besturingselement.


Hier is hoe de CustomComboBox UserControl kan worden gebruikt:

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

En het eindresultaat:

Figuur 1 voer hier de afbeeldingsbeschrijving in figuur 3


Hier is de InverseNullVisibilityConverter die nodig is voor het label op de UserControl, wat slechts een kleine variatie is op de versie van 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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow