TOC

This article has been localized into Danish by the community.

Listekontroller:

ComboBox kontrollen

ComboBox kontrollen er på mange måde ligesom ListBox kontrollen, men den optager meget mindre plads, fordi listen med elementer er skjult, når der ikke er brug for den. ComboBox kontrollen bruges mange steder i Windows, men for at være sikker på at alle ved, hvordan den ser ud og virker, tager vi straks et simpelt eksempel:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxSample" Height="150" Width="200">
    <StackPanel Margin="10">
        <ComboBox>
            <ComboBoxItem>ComboBox Item #1</ComboBoxItem>
            <ComboBoxItem IsSelected="True">ComboBox Item #2</ComboBoxItem>
            <ComboBoxItem>ComboBox Item #3</ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>

I skærmbilledet har jeg aktiveret kontrollen ved at klikke på den, hvilket får listen med elementer til at blive vist. Som du kan se fra koden, er ComboBox i sin simple form meget nem at bruge. Alt, jeg har gjort her, er manuelt at tilføje nogle elementer, og gjort et af dem standardvalget ved at sætte IsSelected egenskaben til sand på det.

Brugerdefineret indhold

I det første eksempel viste vi kun tekst i elementerne, hvilket er ret almindeligt for ComboBox kontrollen, men eftersom ComboBoxItem er en ContentControl, kan vi faktisk bruge hvad som helst som indhold. Lad os prøve at lave en lidt mere sofistikeret liste med elementer:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxCustomContentSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxCustomContentSample" Height="150" Width="200">
    <StackPanel Margin="10">
        <ComboBox>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="/WpfTutorialSamples;component/Images/bullet_red.png" />
                    <TextBlock Foreground="Red">Red</TextBlock>
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="/WpfTutorialSamples;component/Images/bullet_green.png" />
                    <TextBlock Foreground="Green">Green</TextBlock>
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
                    <TextBlock Foreground="Blue">Blue</TextBlock>
                </StackPanel>
            </ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>

For hvert ComboBoxItem har vi nu tilføjet et StackPanel, hvori vi har tilføjet et Image og en TextBlock. Dette giver os fuld kontrol over indholdet såvel som tekstgengivelsen, som du kan se på skærmbilledet, hvor både tekstfarve og billede indikerer en farveværdi.

Databinding af ComboBox

Som du kan se på det første eksempel, er det nemt manuelt at definere elementerne i en ComboBox kontrol vis XAML, men du vil sandsynligvis hurtigt få situationer, hvor du har brug for, at elementerne kommer fra en eller anden datakilde som en database eller blot en liste i hukommelsen. Ved hjælp af WPF databinding og en brugerdefineret skabelon, kan vi nemt gengive en liste af farver inklusive en forhåndsvisning af farven:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxDataBindingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxDataBindingSample" Height="200" Width="200">
    <StackPanel Margin="10">
        <ComboBox Name="cmbColors">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
                        <TextBlock Text="{Binding Name}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace WpfTutorialSamples.ComboBox_control
{
	public partial class ComboBoxDataBindingSample : Window
	{
		public ComboBoxDataBindingSample()
		{
			InitializeComponent();
			cmbColors.ItemsSource = typeof(Colors).GetProperties();
		}
	}
}

Det er faktisk ret simpelt: I code-behind henter jeg en liste af alle farver ved hjælp af Reflection mod Colors klassen. Jeg tildeler denne liste til ItemsSource egenskaben på ComboBox, som derefter gengiver hver farve ved hjælp af den skabelon, jeg har defineret i XAML-delen.

Hvert element består, som angivet af ItemTemplate, af et StackPanel med et Rectangle og en TextBlock, som hver især er bundet til farveværdien. Dette giver os en komplet liste af farver med minimal indsats, og det ser faktisk ret godt ud også.

IsEditable

I de første eksempler kunne brugeren kun vælge elementer fra vores liste, men en af de seje ting ved ComboBox er, at den understøtter muligheden for både at lade brugeren vælge fra listen samt indtaste deres egen værdi. Dette er ekstremt brugbart i situationer, hvor du vil hjælpe brugeren med et sæt præ-definerede muligheder, mens de stadig har mulighed for at indtaste deres ønskede værdi. Dette kontrolleres af IsEditable egenskaben, som ændrer opførsel og udseende af ComboBox ganske meget:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxEditableSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxEditableSample" Height="150" Width="200">
    <StackPanel Margin="10">
        <ComboBox IsEditable="True">
            <ComboBoxItem>ComboBox Item #1</ComboBoxItem>
            <ComboBoxItem>ComboBox Item #2</ComboBoxItem>
            <ComboBoxItem>ComboBox Item #3</ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>

Som du kan se, kan jeg indtaste en fuldstændig anden værdi, eller vælge en fra listen. Hvis jeg vælger en fra listen, overskriver det bare teksten i ComboBox.

Som en fin lille bonus, vil ComboBox automatisk prøve at hjælpe brugeren med at vælge en eksisterende værdi, når brugeren starter indtastningen, som du kan se i næste skærmbillede, hvor jeg har indtastet "Co":

Som standard er der i matchningen ikke forskel på store og små bogstaver, men dette kan du opnå ved at sætte IsTextSearchCaseSensitive til True. Hvis du ikke ønsker denne autofuldførelse overhovedet, kan du slå det fra ved at sætte IsTextSearchEnabled til False.

Arbejde med ComboBox valg

En vigtig del af at bruge ComboBox kontrollen er at være i stand til at læse brugerens valg og endda kontrollere den med kode. I det næste eksempel har jeg genbrugt det databundne ComboBox eksempel, men tilføjet nogle knapper til kontrol af valget. Jeg har også bruge SelectionChanged hændelsen for at fange, når det valgte element ændres enten via kode eller af brugeren, og reagere på det.

Her er eksemplet:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSelectionSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxSelectionSample" Height="125" Width="250">
    <StackPanel Margin="10">
        <ComboBox Name="cmbColors" SelectionChanged="cmbColors_SelectionChanged">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
                        <TextBlock Text="{Binding Name}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
        <WrapPanel Margin="15" HorizontalAlignment="Center">
            <Button Name="btnPrevious" Click="btnPrevious_Click" Width="55">Previous</Button>
            <Button Name="btnNext" Click="btnNext_Click" Margin="5,0" Width="55">Next</Button>
            <Button Name="btnBlue" Click="btnBlue_Click" Width="55">Blue</Button>
        </WrapPanel>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Media;

namespace WpfTutorialSamples.ComboBox_control
{
	public partial class ComboBoxSelectionSample : Window
	{
		public ComboBoxSelectionSample()
		{
			InitializeComponent();
			cmbColors.ItemsSource = typeof(Colors).GetProperties();
		}

		private void btnPrevious_Click(object sender, RoutedEventArgs e)
		{
			if(cmbColors.SelectedIndex > 0)
				cmbColors.SelectedIndex = cmbColors.SelectedIndex - 1;
		}

		private void btnNext_Click(object sender, RoutedEventArgs e)
		{
			if(cmbColors.SelectedIndex < cmbColors.Items.Count-1)
				cmbColors.SelectedIndex = cmbColors.SelectedIndex + 1;
		}

		private void btnBlue_Click(object sender, RoutedEventArgs e)
		{
			cmbColors.SelectedItem = typeof(Colors).GetProperty("Blue");
		}

		private void cmbColors_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
		{
			Color selectedColor = (Color)(cmbColors.SelectedItem as PropertyInfo).GetValue(null, null);
			this.Background = new SolidColorBrush(selectedColor);
		}
	}
}

Den interessante del af dette eksempel er de tre event handlere for vores tre knapper, såvel som SelectionChanged event handleren. I de første to vælger vi bare det forrige eller næste element ved at aflæse SelectedIndex egenskaben og derefter trække en fra eller lægge en til. Ret simpelt og nemt at arbejde med.

I den tredje event handler bruger vi SelectedItem til at vælge et specifikt element baseret på værdien. Jeg laver lidt ekstra arbejde her (med .NET reflection), fordi ComboBox er bundet til en liste af egenskaber, som hver især er en farve, i stedet for en simpel liste af farver, men grundlæggende handler det om at sætte SelectedItem egenskaben til værdien fra en af dem.

I den fjerde og sidste event handler reagerer jeg på ændring af det valgte element. Når det sker, læser jeg den valgte farve (igen via Reflection som beskrevet ovenfor), og bruger derefter den valgte farve til at oprette en ny baggrunndspensen til Window. Effekten kan ses på skærmbilledet.

Hvis du arbejder med en redigerbar ComboBox (IsEditabe egenskaben sat til sand), kan du læse Text egenskaben til at finde værdien, som brugeren har indtastet eller valgt.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!