Programowanie w technologii - ii.uwb.edu.plii.uwb.edu.pl/rybnik/dot NET/PwT.N W2.pdf · podobne do...

57
1/57 Programowanie w technologii .NET wykład 2 – posługiwanie się kontrolkami Własności: // publiczne zmienne składowe: class Element { public string nazwa; } // użycie: Element el = new Element(); el.nazwa = "..."; ... = el.nazwa;

Transcript of Programowanie w technologii - ii.uwb.edu.plii.uwb.edu.pl/rybnik/dot NET/PwT.N W2.pdf · podobne do...

1/57

Programowanie w technologii .NET wykład 2 – posługiwanie się kontrolkami

Własności:

// publiczne zmienne składowe: class Element { public string nazwa; } // użycie: Element el = new Element(); el.nazwa = "..."; ... = el.nazwa;

2/57

// gettery i settery: class Element { private string nazwa; public void setNazwa(string value) { nazwa = value; } public string getNazwa() { return nazwa; } } // użycie: Element el = new Element(); el.setNazwa("..."); ... = el.getNazwa();

3/57

// properties: class Element { public string nazwa; public string Nazwa { set { nazwa = value; } get { return nazwa; } } } // użycie: Element el = new Element(); el.Nazwa = "..."; ... = el.Nazwa;

4/57

// auto-properties: class Element { public string Nazwa { set; get; } } // użycie: Element el = new Element(); el.Nazwa = "..."; ... = el.Nazwa;

5/57

Mechanizm partial class:

class Element { private int x, y; protected string nazwa; public Element(int x, int y) { this.x = x; this.y = y; } public void nazwij(string n) { nazwa = n; } public void przesun(int dx, int dy) { x += dx; y += dy; } }

6/57

partial class Element { private int x, y; public Element(int x, int y) { this.x = x; this.y = y; } public void przesun(int dx, int dy) { x += dx; y += dy; } } partial class Element { protected string nazwa; public void nazwij(string n) { nazwa = n; } }

7/57

Delegacje i zdarzenia:

public delegate void funkcja(string a); class A { public void f(string x) { Console.WriteLine("A.f({0})", x); } } // ... A a = new A(); funkcja delegacja = a.f; // ... delegacja("test");

8/57

public delegate void EventHandler(...); class Button { public event EventHandler Click; protected void mouseButtonDown(...) { // ... Click(...); } } class MyApp { MyApp() { Button btn = new Button(); btn.Click += f; } public void f(...) { // ... } }

9/57

„ręczne” tworzenie okna:

public class Window1 : Window { public Window1() { InitializeComponent(); } private void InitializeComponent() { } }

10/57

public class Window1 : Window { public Window1() { InitializeComponent(); } private void InitializeComponent() { // tytuł i rozmiar: this.Width = this.Height = 300; this.Title = "Okienko"; } }

11/57

public class Window1 : Window { public Window1() { InitializeComponent(); } private void InitializeComponent() { // tytuł i rozmiar: this.Width = this.Height = 300; this.Title = "Okienko"; // przycisk: button1 = new Button(); button1.Content = "Nie dotykać"; button1.Margin = new Thickness(30); } private Button button1; }

12/57

public class Window1 : Window { public Window1() { InitializeComponent(); } private void InitializeComponent() { // tytuł i rozmiar: this.Width = this.Height = 300; this.Title = "Okienko"; // przycisk: button1 = new Button(); button1.Content = "Nie dotykać"; button1.Margin = new Thickness(30); // podpinamy obsługę button1.Click += klik; } private Button button1; private void klik(object sender, RoutedEventArgs e) { button1.Content = "Bzzzzt"; } }

13/57

public class Window1 : Window { public Window1() { InitializeComponent(); } private void InitializeComponent() { // tytuł i rozmiar: this.Width = this.Height = 300; this.Title = "Okienko"; // przycisk: button1 = new Button(); button1.Content = "Nie dotykać"; button1.Margin = new Thickness(30); // podpinamy obsługę button1.Click += klik; // panel na zawartość: DockPanel panel = new DockPanel(); // przycisk wrzucamy na panel: panel.AddChild(button1); // a panel na okno: this.AddChild(panel); } private Button button1; private void klik(object sender, RoutedEventArgs e) { button1.Content = "Bzzzzt"; } }

14/57

public partial class Window1 : Window { private void InitializeComponent() { this.Width = this.Height = 300; this.Title = "Okienko"; button1 = new Button(); button1.Content = "Nie dotykać"; button1.Margin = new Thickness(30); button1.Click += klik; DockPanel panel = new DockPanel(); panel.AddChild(button1); this.AddChild(panel); } private Button button1; } public class Window1 : Window { public Window1() { InitializeComponent(); } private void klik(object sender, RoutedEventArgs e) { button1.Content = "Bzzzzt"; } }

15/57

<Window x:Class="WpfApplication1.Window1" ... Width="300" Height="300" Title="Okienko"> <DockPanel> <Button Margin="30" Name="button1" Click="klik"> Nie dotykać </Button> </DockPanel> </Window> public class Window1 : Window { public Window1() { InitializeComponent(); } private void klik(object sender, RoutedEventArgs e) { button1.Content = "Bzzzzt"; } }

16/57

posługiwanie się własnościami:

<Button Name="btn1">OK</Button> w kodzie: btn1.Content = "Not OK"; posługiwanie się zdarzeniami:

<Button Name="btn1" Click="klik">OK</Button> albo w kodzie: btn1.Click += new RoutedEventHandler(klik); lub: btn1.Click += klik; i odłączanie: btn1.Click -= klik; metoda obsługi zdarzenia: void klik(object sender, RoutedEventArgs e) { ... }

17/57

Content Controls – kontrolki zawartości

Mogą zawierać pojedynczy element. Ten sam mechanizm zagnieżdżania, który pozwalał

układać nam elementy w kontenerach, służy do ustawienia zawartości kontrolki. <StackPanel> <Button Margin="3" Padding="5">Napis</Button> <Button Margin="3" Padding="5"> <Image Source="lolface.png" Stretch="None" /> </Button> <Button Margin="3" Padding="5"> <StackPanel> <Label Margin="3">Napis i obrazek</Label> <Image Source="lolface.png" Stretch="None" /> </StackPanel> </Button> </StackPanel>

Mają właściwość Content.

18/57

19/57

uwaga: tylko część elementów umieszczanych na oknie to kontrolki (kontrolki to elementy z

którymi użytkownik może wchodzić w interakcję) Podstawowe własności kontrolek:

Dotyczące rozmieszczenia (Margin, Padding, HorizontalAlignment, VerticalContentAlignment, etc.)

20/57

Wybór czcionek: <WrapPanel Margin="3"> <Label FontFamily="Arial">Arial</Label> <Label FontFamily="Times New Roman">Times New Roman</Label> <Label FontFamily="Courier New">Courier New</Label> <Label FontFamily="Comic Sans MS">Comic Sans MS</Label> <Label FontSize="24">Size 24</Label> <Label FontSize="32">Size 36</Label> <Label FontStyle="Italic">Italic</Label> <Label FontWeight="Bold">Bold</Label> <Label FontStyle="Italic" FontWeight="Bold">Italic Bold</Label> </WrapPanel>

Właściwości czcionek można ustawić dla okna, a wszystkie elementy je odziedziczą

(o ile nie nadpiszą własnymi).

21/57

Wybór tła, kolorów, obramowania <WrapPanel Margin="2"> <Label Foreground="Red">Red</Label> <Label Foreground="BlueViolet">BlueViolet</Label> <Label Background="GreenYellow">GreenYellow</Label> <Label Background="SkyBlue">SkyBlue</Label> <Label Background="DarkGoldenrod" Foreground="Khaki">...</Label> <Label BorderBrush="Maroon" BorderThickness="1">Maroon 1</Label> <Label BorderBrush="Gold" BorderThickness="5">Gold 5</Label> </WrapPanel>

Albo: <Label Foreground="#FFFF0000">Red</Label>

22/57

Background, Foreground są typu Brush, a nie Color – pozwala to na używanie

różnego rodzaju wypełnień (gradienty, tekstura, …): <Label>Red <Label.Foreground> <SolidColorBrush Color="Red" /> </Label. Foreground > </Label>

Ręcznie: pędzel z koloru:

button1.Background = new SolidColorBrush(Colors.GreenYellow);

z koloru systemowego:

button1.Background = new SolidColorBrush(SystemColors.ControlColor);

pędzle systemowe:

button1.Background = SystemColors.ControlBrush;

z koloru w RGB:

button1.Foreground = new SolidColorBrush(Color.FromRgb(0, 128, 255));

z koloru w ARGB – z wartością Alpha: button1.Foreground = new SolidColorBrush(Color.FromArgb(128, 0, 128, 255));

(nazwane kolory, znane z HTMLa, są statycznymi właściwościami klasy Colors)

23/57

Widoczność: <WrapPanel Margin="2"> <Button>Pierwszy</Button> <Button Visibility="Hidden">Drugi</Button> <Button>Trzeci</Button> </WrapPanel>

Przeźroczystość: <WrapPanel Background="GreenYellow"> <Button>Pełny</Button> <Button Opacity="0.5">Opacity</Button> <Button Background="#80FFFFFF">Kolor</Button> </WrapPanel>

Dostępność – wyszarzenie: <WrapPanel> <Button>Normalny</Button> <Button IsEnabled="False">Niedostępny</Button> </WrapPanel>

24/57

Przycisk – Button <StackPanel> <DockPanel> <Label Margin="3">Podaj kod:</Label> <TextBox Margin="3"></TextBox> </DockPanel> <WrapPanel HorizontalAlignment="Right"> <Button Margin="3" Padding="15,3" IsDefault="True" Click="OkClick">OK</Button> <Button Margin="3" Padding="15,3" IsCancel="True" Click="CancelClick">Anuluj</Button> </WrapPanel> </StackPanel>

25/57

private void CancelClick(object sender, RoutedEventArgs e) { MessageBox.Show("Nacisnąłeś Anuluj"); } private void OkClick(object sender, RoutedEventArgs e) { MessageBox.Show("Nacisnąłeś OK"); }

Zdarzenie Click. Właściwości:

o IsCancel (naciśnięcie Esc automatycznie go uruchomi) o IsDefault (ma specjalne graficzne oznaczenie, uruchomi go naciśnięcie

Enter (o ile nie stoimy na innym przycisku)) o (ale zamknięciem okna musimy zająć się sami)

26/57

CheckBox i RadioButton – są szczególnymi typami przycisków. CheckBox:

właściwość IsChecked – przyjmuje wartość true, false oraz null (stan niezdefiniowany)

właściwość IsThreeState – ustawiona na true oznacza, że użytkownik może

wybrać stan niezdefiniowany <StackPanel> <CheckBox Margin="3" IsChecked="True">Tak</CheckBox> <CheckBox Margin="3" IsChecked="False">Nie</CheckBox> <CheckBox Margin="3" IsChecked="{x:Null}">Może?</CheckBox> </StackPanel>

27/57

RadioButton: wybór jednego z grupy (na podstawie zawierania elementów w kontenerze) możliwe definiowanie własnych grup (właściwość GroupName)

<StackPanel> <RadioButton Margin="3" IsChecked="True">Opcja A</RadioButton> <RadioButton Margin="3">Opcja B</RadioButton> <RadioButton Margin="3">Opcja C</RadioButton> </StackPanel>

28/57

GroupBox Ramka z nagłówkiem, służy do grupowania innych kontrolek Zawiera pojedynczy element!

<GroupBox Header="Wybierz opcję" Padding="5" Margin="5"> <StackPanel> <RadioButton Margin="3">Pierwsza</RadioButton> <RadioButton Margin="3">Druga</RadioButton> <RadioButton Margin="3">Trzecia</RadioButton> </StackPanel> </GroupBox>

29/57

W nagłówku możemy umieścić również inne elementy. <GroupBox Padding="5" Margin="5"> <GroupBox.Header> <CheckBox Click="adresClick" Name="adresCheck" IsChecked="true"> Adres</CheckBox> </GroupBox.Header> <Grid Name="adresGrid"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Label Margin="3">Imię i nazwisko:</Label> <Label Margin="3" Grid.Row="1">Ulica:</Label> <Label Margin="3" Grid.Row="2">Kod i miejscowość:</Label> <TextBox Margin="3" Grid.Column="1" /> <TextBox Margin="3" Grid.Column="1" Grid.Row="1"/> <TextBox Margin="3" Grid.Column="1" Grid.Row="2"/> </Grid> </GroupBox>

30/57

private void adres(object sender, RoutedEventArgs e) { if (adresCheck.IsChecked == true) adresGrid.IsEnabled = true; else adresGrid.IsEnabled = false; }

31/57

Przykład praktyczny: <StackPanel> <GroupBox Header="Wybierz dodatki" Padding="5" Margin="5"> <StackPanel Name="dodatki" CheckBox.Click="klik"> <CheckBox Margin="3" Tag="Pieczarki">Pieczarki</CheckBox> <CheckBox Margin="3" Tag="Salami">Salami</CheckBox> <CheckBox Margin="3" Tag="Oliwki">Oliwki</CheckBox> <CheckBox Margin="3" Tag="Ser">Ser</CheckBox> </StackPanel> </GroupBox> <Label Margin="3" Name="wybór"/> </StackPanel>

32/57

private void klik(object sender, RoutedEventArgs e) { string str = "Wybrałeś: "; foreach (CheckBox cbx in dodatki.Children) { if(cbx.IsChecked == true) str += cbx.Tag + ", "; } wybór.Content = str; }

33/57

Label – etykieta To również jest kontrolka zawartości Pozwala na definiowanie mnemoników – skrótów odsyłających do kontrolki

<StackPanel> <CheckBox Margin="3">Wybór _pierwszy</CheckBox> <CheckBox Margin="3">Wybór _drugi</CheckBox> <CheckBox Margin="3">Wybór _trzeci</CheckBox> <Label Target="pole" Margin="3">D_ane:</Label> <TextBox Name="pole" Margin="3"></TextBox> </StackPanel>

34/57

ToolTip – podpowiedzi: Nie reagują na wejście użytkownika

<StackPanel> ... <Button ToolTip="Naciśnij mnie" Margin="3" Padding="3"> ... </Button> ... </StackPanel>

35/57

Mogą być bardziej złożone: <Button Margin="3" Padding="3"> <Button.ToolTip> <StackPanel> <Label FontWeight="Bold" Background="Blue" Foreground="White"> Przycisk "Dwa" </Label> <TextBlock Padding="10" Width="200" TextWrapping="WrapWithOverflow"> Opis działania drugiego przycisku zajmuje parę linijek tekstu. </TextBlock> <Line Stroke="Black" StrokeThickness="1" X2="200"/> <Label FontWeight="Bold">F1 - dodatkowa pomoc.</Label> </StackPanel> </Button.ToolTip> Dwa </Button>

36/57

elementy na tooltipie nie reagują na wejście użytkownika!

właściwości kontrolki Tooltip pozwalają ustawić położenie, czas wyświetlania, czas

oczekiwania, etc.

37/57

Popup: podobne do tooltipa, ale nie znika ani nie pojawia się automatycznie, a jego

elementy mogą przyjmować wejście („łapie focusa”)

w XAMLu tylko definiujemy <Button Click="klik">Opcje</Button> <Popup Name="opcje" StaysOpen="False" Placement="Mouse" PopupAnimation="Slide"> <Border BorderBrush="Black" BorderThickness="1" Background="White"> <StackPanel> <CheckBox>Opcja 1</CheckBox> <CheckBox>Opcja 2</CheckBox> <CheckBox>Opcja 3</CheckBox> </StackPanel> </Border> </Popup> a otwieramy w kodzie: private void klik(object sender, RoutedEventArgs e) { opcje.IsOpen = true; }

38/57

Kursor myszy

właściwość Cursor można ustawić dla każdego elementu kursory systemowe dostępne jako statyczne właściwości klasy Cursors: button1.Cursor = Cursors.Wait; a w XAMLu: <Button Cursor="Help">Help</Button>

jeśli ustawienia kursora się nakładają (np. okna i kontrolki na nim umieszczonej) –

wybierana jest właściwość bardziej specyficzna (czyli nad kontrolką jest kursor kontrolki, a

nad resztą okna – kursor okna)

przeciwdziała temu:

ForceCursor – aby ojciec nadpisał kursora dzieci inne rozwiązanie – kursor dla każdego elementu każdego okna aplikacji: Mouse.OverrideCursor = Cursors.Wait; własne kursory: this.Cursor = new Cursor(Path.Combine(applicationDir, "mycursor.ani"));

39/57

Expander

Ukrywa swoją zawartość, którą użytkownik może rozwinąć. IsExpanded – sterujemy rozwinięciem/zwinięciem ExpandDirection – kierunek rozwijania (domyślne Down lub Up, Left, Right)

<StackPanel> <Expander Header="pierwsza">...</Expander> <Expander Header="druga"> <StackPanel> ... </StackPanel> </Expander> <Expander Header="trzecia">...</Expander> </StackPanel>

40/57

Kontrolki tekstowe: TextBox Wprowadzanie kilku linijek tekstu:

AcceptsReturn – ustawione na true pozwala na wprowadzanie Enterów AcceptsTab – podobnie z Tabami TextWrapping (ustawiona na Wrap lub WrapWithOverflow) – zawijanie zbyt

długich wierszy (WrapWithOverflow pozwala wypływać poza kontrolkę zbyt

długim liniom, Wrap zawsze łamie tekst) <TextBox TextWrapping="Wrap" Margin="3"> AlamakotaAlamakota Alamakota</TextBox> <TextBox TextWrapping="WrapWithOverflow" Margin="3"> AlamakotaAlamakota Alamakota</TextBox>

41/57

Ponadto: MinLines i MaxLines pozwalają na ustawienie rozmiaru kontrolki aby była w

stanie wyświetlić zadeklarowaną liczbę linii LineCount – pozwala sprawdzić faktyczną liczbę linii VerticalScrollBarVisibility – ustawiając na Visible lub Auto dodajemy pasek

przewijania IsReadOnly – tekst tylko do odczytu (ale pozwala wybrać go i skopiować w

odróżnieniu od etykiety) Text – zawartość tekstowa Text Selection:

<TextBox Name="box">Ala ma kota. Ala ma kota</TextBox> <Button Click="klik">zaznacz</Button> private void klik(object sender, RoutedEventArgs e) { box.SelectionStart = 5; box.SelectionLength = 5; box.SelectedText = "xxx"; box.Focus(); }

42/57

Focus() – przejęcie „fokusa” <DockPanel> <Label DockPanel.Dock="Left">Dane</Label> <Button DockPanel.Dock="Right" Click="Clear">Wyczyść</Button> <TextBox Name="tekst"/> </DockPanel> private void Clear(object sender, RoutedEventArgs e) { tekst.Text = ""; tekst.Focus(); }

Kontrolka, która aktualnie przyjmuje wejście z klawiatury, ma „focusa”.

właściwość Focusable – czy może przyjąć focusa

Przechodzenie Tabem – na podstawie hierarchii zagnieżdżenia.

o Można to zmienić, wybierając własną sekwencję przez ustawienie właści-

wości TabIndex (0 – pierwszy, a potem wraz ze wzrostem).

o IsTabStop – jeśli false, to danego elementu nie zwiedzamy Tabem (ale na-

dal może być Focusable)

43/57

PasswordBox

Password – pozwala pobrać hasło (hasło przechowywane jest w pamięci w postaci zaszyfrowanej)

<StackPanel> <DockPanel> <Label Margin="3">Hasło</Label> <PasswordBox Name="hasło" Margin="3"/> </DockPanel> <Button HorizontalAlignment="Center" Margin="3" Padding="15,3" Click="OkClick">OK</Button> </StackPanel> private void OkClick(object sender, RoutedEventArgs e) { MessageBox.Show("Twoje hasło to " + hasło.Password + "!"); }

44/57

Range-Based Controls (ScrollBar, Slider, ProgressBar)

Przyjmują pewną wartość z ustalonego zakresu Value (aktualna wartość) – jej zmiana odpala ValueChanged Maximum i Minimum – dolny i górny zakres

Slider:

Orientation – w poziomie czy w pionie? TickPlacement – None, TopLeft lub BottomRight TickFrequency – odległość między tickami IsSnapToTickEnabled – doklejanie do ticków

<Slider Minimum="1" Value="15" Maximum="100" TickFrequency="10" TickPlacement="TopLeft"/>

45/57

Ticks – kolekcja położeń (jeśli np. mają być nieregularnie rozmieszczone) IsSelectionRangeEnabled – wybór zakresu na ścieżce (użyteczne np. w media

playerach) (przy pomocy SelectionStart i SelectionEnd) <Slider Margin="5" Value="1.5"/> <Slider Margin="5" Value="1.5" TickFrequency="1" TickPlacement="BottomRight"/> <Slider Margin="5" Value="1.5" Ticks="1,2,3,5,8" TickPlacement="BottomRight"/> <Slider Margin="5" Value="1.5" TickFrequency="2.5" TickPlacement="BottomRight" IsSelectionRangeEnabled="True" SelectionStart="3" SelectionEnd="7"/>

46/57

Inny przykład: <StackPanel Margin="5"> <Slider Margin="5" Minimum="10" Maximum="50" Value="12" TickFrequency="5" TickPlacement="BottomRight" ValueChanged="slide"/> <Label HorizontalAlignment="Center"> To jest test slidera. </Label> </StackPanel> private void slide(object sender, RoutedPropertyChangedEventArgs<double> e) { this.FontSize = e.NewValue; }

47/57

ProgressBar

Nie zapewnia interakcji, a jedynie wyświetla jakąś informację dla użytkownika. Pozwala też na stan nieokreślony (gdy nie wiemy ile czasu potrwa zdarzenie): <ProgressBar Value="50" Height="18"/>

<ProgressBar Height="18" IsIndeterminate="True" />

48/57

Menu

Mamy dostępne dwie kontrolki: Menu (menu aplikacji) i ContextMenu (menu

kontekstowe). Menu:

o Podlega zwyczajnym regułom rozmieszczania elementów (przeważnie jest

na szczycie DockPanela lub w pierwszym wierszu Grida). o Można dodać dowolną liczbę menu. o Własność IsMainMenu ustawiona na true powoduje, że menu dostanie

focusa po naciśnięciu klawisza Alt lub F10. ContextMenu:

o Nie jest umieszczane w oknie, lecz ustawiane dla konkretnego elementu. MenuItem

Menu zbudowane jest z elementów typu MenuItem oraz Separator. MenuItem to rozwijalne podmenu. Separator to po prostu pozioma linia, nie reagująca na wejście użytkownika. Menu możemy (teoretycznie) wypełniać dowolnymi elementami (ale lepiej nie

przesadzać).

49/57

<Menu DockPanel.Dock="Top"> <MenuItem Header="File"> <MenuItem Header="New"/> <MenuItem Header="Open"/ > <MenuItem Header="Save"/> <Separator></Separator> <MenuItem Header="Exit"/> </MenuItem> <MenuItem Header="Edit"> <MenuItem Header="Undo"/> <MenuItem Header="Redo"/> <Separator></Separator> <MenuItem Header="Cut"/> <MenuItem Header="Copy"/> <MenuItem Header="Paste"/> </MenuItem> </Menu>

MenuItem reaguje na kliknięcie zdarzeniem Click. Wyświetla: tekst (Header), ikonę (Icon), znacznik wyboru (IsChecked – wybranie

dodatkowo IsCheckable kliknięcie zmienia stan wyboru), skrót klawiaturowy

(InputGestureText – to jest tylko tekstu skrótu, nie zapewnia to obsługi).

50/57

ToolBar i StatusBar

<ToolBar DockPanel.Dock="Top"> <Button>New</Button> <Button>Open</Button> <Button>Save</Button> <Separator/> <Button>Cut</Button> <Button>Copy</Button> <Button>Paste</Button> </ToolBar> <StatusBar DockPanel.Dock="Bottom"> <Label>Ready</Label> </StatusBar>

51/57

Items Controls – kontrolki elementów

Pozwalają na wyświetlanie listy wielu elementów.

ListBox

SelectionMode można ustawić na: Multiple (wybieramy kilka klikając na nich) lub

Extended (klikając z Ctrl lub Shift) <ListBox SelectionMode="Multiple"> <ListBoxItem>jeden</ListBoxItem> <ListBoxItem>dwa</ListBoxItem> <ListBoxItem>trzy</ListBoxItem> <ListBoxItem>cztery</ListBoxItem> </ListBox>

52/57

Na liście można umieszczać też inne elementy: <ListBox> <ListBoxItem> <Image Source="uwaga.png"></Image> </ListBoxItem> <ListBoxItem> <Image Source="error.png"></Image> </ListBoxItem> </ListBox>

53/57

a nawet: <ListBox> <StackPanel Orientation="Horizontal"> <Image Source="uwaga.png" Width="30" Height="30"></Image> <Label VerticalContentAlignment="Center">uwaga</Label> </StackPanel> <StackPanel Orientation="Horizontal"> <Image Source="error.png" Width="30" Height="30"></Image> <Label VerticalContentAlignment="Center">błąd</Label> </StackPanel> </ListBox>

54/57

pozwala to stworzyć listę wyboru: <ListBox SelectionMode="Extended" Name="lista" SelectionChanged="lst_SelChanged" CheckBox.Click="lst_SelChanged"> <CheckBox>jeden</CheckBox> <CheckBox>dwa</CheckBox> <CheckBox>trzy</CheckBox> <CheckBox>cztery</CheckBox> </ListBox> <Label Name="opis"/> private void lst_SelChanged(object sender, EventArgs e) { StringBuilder str = new StringBuilder(); foreach (CheckBox item in lista.Items) { if (item.IsChecked == true) { str.Append(item.Content); str.Append("\r\n"); } } opis.Content = str.ToString(); }

55/57

ComboBox

działa podobnie jak ListBox, ale ukazuje jedynie jeden wybrany element

<ComboBox IsEditable="True"> <ComboBoxItem>jeden</ComboBoxItem> <ComboBoxItem>dwa</ComboBoxItem> <ComboBoxItem>trzy</ComboBoxItem> <ComboBoxItem>cztery</ComboBoxItem> </ComboBox >

Właściwość IsEditable ustawiona na true pozwala użytkownikowi wprowadzić własną wartość.

56/57

Programistyczny dostęp do listy elementów: <DockPanel Margin="3"> <ToolBar DockPanel.Dock="Top"> <Button Click="Dodaj">Dodaj</Button> <Button Click="Usuń">Usuń</Button> </ToolBar> <ListBox Margin="3" Name="lista"/> </DockPanel> private void Dodaj(object sender, RoutedEventArgs e) { lista.Items.Add(new ListBoxItem { Content="nowy element" }); } private void Usuń(object sender, RoutedEventArgs e) { if(lista.SelectedIndex >= 0) lista.Items.RemoveAt(lista.SelectedIndex); }

57/57