Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 5. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Weitere .NET-Datentypen
7 Weitere Möglichkeiten von C#
8 Auflistungsklassen (Collections)
9 Fehlerbehandlung und Debugging
10 LINQ to Objects
11 Multithreading und die Task Parallel Library (TPL)
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 Einige wichtige .NET-Klassen
15 Projektmanagement und Visual Studio 2010
16 XML
17 WPF – Die Grundlagen
18 WPF-Containerelemente
19 WPF-Steuerelemente
20 Konzepte der WPF
21 Datenbindung
22 2D-Grafik
23 ADO.NET – verbindungsorientierte Objekte
24 ADO.NET – Das Command-Objekt
25 ADO.NET – Der SqlDataAdapter
26 ADO.NET – Daten im lokalen Speicher
27 ADO.NET – Aktualisieren der Datenbank
28 Stark typisierte DataSets
29 LINQ to SQL
30 Weitergabe von Anwendungen
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2010 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2010

Visual C# 2010
geb., mit DVD
1295 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1552-7
Pfeil 19 WPF-Steuerelemente
Pfeil 19.1 Hierarchie der WPF-Komponenten
Pfeil 19.2 Steuerelemente positionieren
Pfeil 19.2.1 Die Eigenschaften »Top«, »Bottom«, »Right« und »Left«
Pfeil 19.2.2 Außenrand mit der Eigenschaft »Margin« festlegen
Pfeil 19.2.3 Innenrand mit der Eigenschaft »Padding« festlegen
Pfeil 19.3 Allgemeine Eigenschaften der WPF-Komponenten
Pfeil 19.3.1 Die Eigenschaft »Content«
Pfeil 19.3.2 Größe einer Komponente
Pfeil 19.3.3 Ausrichtung einer Komponente
Pfeil 19.3.4 Die Eigenschaften »Padding« und »Margin«
Pfeil 19.3.5 Sichtbarkeit eines Steuerelements
Pfeil 19.3.6 Farbeinstellungen
Pfeil 19.3.7 Schriften
Pfeil 19.4 Buttons
Pfeil 19.4.1 Die Basisklasse »ButtonBase«
Pfeil 19.4.2 Das Steuerelement »Button«
Pfeil 19.4.3 Das Steuerelement »ToggleButton«
Pfeil 19.4.4 Das Steuerelement »RepeatButton«
Pfeil 19.4.5 Das Steuerelement »Checkbox«
Pfeil 19.4.6 Das Steuerelement »RadioButton«
Pfeil 19.5 Einfache Eingabesteuerelemente
Pfeil 19.5.1 Das Steuerelement »Label«
Pfeil 19.5.2 Das Steuerelement »TextBox«
Pfeil 19.5.3 Das Steuerelement »PasswordBox«
Pfeil 19.5.4 Das Steuerelement »TextBlock«
Pfeil 19.5.5 Das Steuerelement »Tooltip«
Pfeil 19.6 FlowDocuments
Pfeil 19.6.1 Allgemeine Beschreibung
Pfeil 19.6.2 Eigenschaften eines FlowDocuments
Pfeil 19.6.3 Blöcke eines FlowDocuments
Pfeil 19.6.4 Inline-Elemente
Pfeil 19.6.5 FlowDocuments mit Code erzeugen
Pfeil 19.6.6 Speichern und Laden von FlowDocuments
Pfeil 19.7 Das Element »FlowDocumentViewer«
Pfeil 19.7.1 Das Anzeigeelement »FlowDocumentScrollViewer«
Pfeil 19.7.2 Das Anzeigeelement »FlowDocumentPageViewer«
Pfeil 19.7.3 Das Anzeigeelement »FlowDocumentReader«
Pfeil 19.8 XPS-Dokumente mit »DocumentViewer«
Pfeil 19.8.1 Allgemeines zum XPS-Format
Pfeil 19.8.2 Beispielprogramm
Pfeil 19.8.3 Das Steuerelement »RichTextBox«
Pfeil 19.9 WPF-Listenelemente – ItemControls
Pfeil 19.9.1 Das Steuerelement »ListBox«
Pfeil 19.9.2 ComboBox
Pfeil 19.9.3 Das Steuerelement »ListView«
Pfeil 19.9.4 Das Steuerelement »TreeView«
Pfeil 19.9.5 Das Steuerelement »TabControl«
Pfeil 19.9.6 Menüleisten
Pfeil 19.9.7 Kontextmenüs
Pfeil 19.9.8 Symbolleisten
Pfeil 19.9.9 Die Statusleiste
Pfeil 19.10 Weitere Steuerelemente
Pfeil 19.10.1 Die »ProgressBar«
Pfeil 19.10.2 Das Steuerelement »Slider«
Pfeil 19.10.3 Das »GroupBox«-Steuerelement
Pfeil 19.10.4 Das Steuerelement »ScrollViewer«
Pfeil 19.10.5 Das Steuerelement »Expander«
Pfeil 19.10.6 Das Steuerelement »Border«
Pfeil 19.10.7 Die »Image«-Komponente
Pfeil 19.10.8 Grafik zur Laufzeit laden


Galileo Computing - Zum Seitenanfang

19.9 WPF-Listenelemente – ItemControls Zur nächsten ÜberschriftZur vorigen Überschrift

Eine Reihe verschiedener WPF-Steuerelemente sind in der Lage, Listen anzuzeigen. Zu diesen Controls werden unter anderem die ListBox, die ComboBox, das TabControl, die ListView und das TreeView-Control gerechnet. Die von diesen Controls dargestellten Listenelemente lassen sich in zwei Gruppen kategorisieren:

  • ItemControls
  • HeaderedItemControls

Listensteuerelemente, die Listenelemente der Gruppe der ItemControls anzeigen, zeichnen sich durch die Eigenschaft Items aus. Diese Eigenschaft gewährleistet den Zugriff auf die einzelnen Elemente der Liste, der über den Index des Elements erfolgen kann. Typische Vertreter für Steuerelemente, die ItemControls aufnehmen, sind die ListBox und die ComboBox. Je nach Typ des anzeigenden Controls werden die Listenelemente durch besondere Klassen beschrieben. Im Fall einer ListBox handelt es sich um ListBoxItem, bei der ComboBox sind es Elemente vom Typ ComboBoxItem.

Von der Klasse ItemControls ist die Klasse HeaderedItemControls abgeleitet. Es ist die Eigenschaft Header, die Elemente dieses Typs auszeichnet. Mit der Eigenschaft Header kann einem Element ein »Titel« zugewiesen werden, der einer Spalte zugeordnet wird. Steuerelemente der Gruppe der HeaderedItemControls bilden somit keine einfache lineare, sondern eine hierarchische Struktur ab. Typische Vertreter dieser Gruppe sind die Klassen MenuItem, TreeView und auch ToolBar.


Galileo Computing - Zum Seitenanfang

19.9.1 Das Steuerelement »ListBox« Zur nächsten ÜberschriftZur vorigen Überschrift

ListBoxen bieten eine Liste von möglichen Auswahlalternativen an, aus denen der Anwender eine oder auch mehrere wählen kann. Per Vorgabe gestattet eine ListBox nur die Einfachauswahl. Damit auch die Auswahl mehrerer Einträge möglich ist, müssen Sie die Eigenschaft SelectionMode auf Multiple oder Extended festlegen. Multiple gestattet dabei die Auswahl durch einen einfachen Klick. Bei der Einstellung Extended muss der Anwender beim Anklicken des Listenelements die Taste Shift -Taste gedrückt halten.

Um eine klassische ListBox zu erzeugen, verwenden Sie für jedes Listenelement die Klasse ListBoxItem.


<ListBox Name="ListBox1">
  <ListBoxItem>Peter</ListBoxItem>
  <ListBoxItem>Franz</ListBoxItem>
  <ListBoxItem>Rolf</ListBoxItem>
  <ListBoxItem>Hans-Günther</ListBoxItem>
</ListBox>

Sie können der ListBox sowohl im XAML-Code als auch in der Code-Behind-Datei Listenelemente hinzufügen. Alle Listenelemente werden in der ListBox von einer Collection verwaltet, deren Referenz die Eigenschaft Items liefert. Durch Aufruf der Methode Add fügen Sie nach Bedarf Elemente hinzu:


ListBox1.Items.Add("Beate");
ListBox1.Items.Add("Gudrun");

Damit nicht genug: Anstatt eine Liste von ListBoxItems zu definieren, können Sie auch andere Steuerelemente angeben. Im folgenden Codefragment sind beispielsweise CheckBox-Elemente hinzugefügt worden:


<ListBox Name="ListBox1">
  <CheckBox Name="A" Margin="3">Peter</CheckBox>
  <CheckBox Name="B" Margin="3">Franz</CheckBox>
  <CheckBox Name="C" Margin="3">Rolf</CheckBox>
  <CheckBox Name="D" Margin="3">Hans-Günter</CheckBox>
</ListBox>

Das Hinzufügen von ListBox-Einträgen ist auch mittels Programmcode möglich:


CheckBox chk1 = new CheckBox();
chk1.Content = "Beate";
chk1.Margin = new Thickness(3);
CheckBox chk2 = new CheckBox();
chk2.Content = "Gudrun";
chk3.Margin = new Thickness(3);
ListBox1.Items.Add(chk1);
ListBox1.Items.Add(chk2);

Beachten Sie bei diesem Code, dass die Eigenschaft Margin durch den Typ Thickness beschrieben wird.

Abbildung 19.22 ListBox mit CheckBoxen

Zugriff auf das ausgewählte Element

Das ausgewählte Element bzw. die ausgewählten Elemente werden in der Regel im Programmcode für die weiteren Operationen benutzt. Die ListBox stellt Eigenschaften bereit, die es erlauben, die entsprechenden Elemente auszuwerten.


Tabelle 19.11 Eigenschaften der ListBox (Elementauswahl)

Eigenschaft Beschreibung
SelectedIndex

Gibt den Index des ersten Elements in der aktuellen Auswahl zurück. Ist die Auswahl leer, ist der Rückgabewert -1. Mit dieser Eigenschaft kann auch ein Element vorselektiert werden.

SelectedItem

Gibt das erste Element in der aktuellen Auswahl zurück. Ist die Auswahl leer, ist der Rückgabewert null.

SelectedItems

Ruft alle ausgewählten Elemente ab.


Möchten Sie, dass ein bestimmtes Listenelement beim Starten des Windows vorselektiert ist, verwenden Sie die Eigenschaft SelectedIndex. Da die Liste der Elemente nullbasiert ist, genügt die Anweisung


ListBox1.SelectedIndex = 0;

um das erste Element zu markieren.

Etwas schwieriger gestaltet es sich, den Inhalt eines ausgewählten Elements auszuwerten. Nehmen wir dazu den folgenden XAML-Code:


<ListBox Name="ListBox1">
  <ListBoxItem>Frankreich</ListBoxItem>
  <ListBoxItem>Italien</ListBoxItem>
  <ListBoxItem>Polen</ListBoxItem>
  <ListBoxItem>Dänemark</ListBoxItem>
</ListBox>

Um sich den Inhalt des ausgewählten Elements in einer MessageBox anzeigen zu lassen, ist der folgende Code notwendig:


MessageBox.Show(((ListBoxItem)ListBox1.SelectedItem).Content.ToString());

Zuerst lassen wir uns das erste ausgewählte Element mit der Methode SelectedItem zurückgeben und konvertieren es in den Typ, der die Listenelemente beschreibt. Hier handelt es sich um ListItem. ListItem verfügt über die Eigenschaft Content, die vom Typ Object ist. Da wir aber wissen, dass es sich um eine Zeichenfolge handelt, können wir diese mit ToString abrufen.

Auswahl mehrerer Elemente

Durch Einstellen der Eigenschaft SelectionMode auf Multiple oder Extended kann der Anwender mehrere Listenelemente gleichzeitig auswählen. Um diese auszuwerten, eignet sich SelectedItems, die die Liste aller ausgewählten Elemente bereitstellt. Sie können diese Liste beispielsweise in einer foreach-Schleife durchlaufen:


private void btnShowItems_Click(object sender, RoutedEventArgs e) {
  string items = "";
  foreach (ListBoxItem item in ListBox1.SelectedItems)
    items += item.Content +"\n";
    MessageBox.Show(items);
}


Galileo Computing - Zum Seitenanfang

19.9.2 ComboBox Zur nächsten ÜberschriftZur vorigen Überschrift

Die ComboBox ähnelt der oben behandelten ListBox. Der Unterschied zwischen diesen beiden Steuerelementen ist, dass die ComboBox immer nur ein Element anzeigt und somit auch nicht viel Platz in Anspruch nimmt.

Per Vorgabe kann der Anwender zur Laufzeit keine neuen Elemente in die ComboBox eintragen. Möchten Sie das aber zulassen, müssen Sie die Eigenschaft IsEditable = true setzen. Mit der Eigenschaft ReadOnly legen Sie fest, ob der Inhalt der ComboBox editiert werden kann. Die Kombination beider Eigenschaften entscheidet maßgeblich über die Handhabung des Steuerelements. Stellen Sie beispielsweise beide auf True ein, kann der Anwender kein Zeichen in die ComboBox eintragen. Ändern Sie allerdings IsEditable auf False, kann der Anwender bei fokussierter ComboBox ein Zeichen an der Tastatur eingeben. Befindet sich ein Element mit dem entsprechenden Anfangsbuchstaben in der Liste der Elemente, wird dieses ausgewählt.

Die einer ComboBox zugeordneten Elemente sind vom Typ ComboBoxItem:


<ComboBox Height="20" Name="comboBox1" Width="120">
  <ComboBoxItem>Berlin</ComboBoxItem>
  <ComboBoxItem>Hamburg</ComboBoxItem>
  <ComboBoxItem>Bremen</ComboBoxItem>
  <ComboBoxItem>Düsseldorf</ComboBoxItem>
  <ComboBoxItem>Dresden</ComboBoxItem>
  <ComboBoxItem>München</ComboBoxItem>
</ComboBox>

Um per Programmcode ein Element hinzuzufügen, rufen Sie mit Items die ItemCollection der ComboBox ab. Deren Methode Add übergeben Sie einfach den gewünschten zusätzlichen Eintrag:


comboBox1.Items.Add("Stuttgart");

Das ausgewählte Element können Sie mit der Eigenschaft Text abrufen. Mit dieser Eigenschaft lässt sich auch festlegen, welches Listenelement nach dem Laden des Windows angezeigt werden soll. Gleichwertig können Sie mit SelectedIndex auch den Index des gewünschten Elements angeben.

Nur zwei Ereignisse sind für die ComboBoxen DropDownOpened und DropDownClosed spezifisch. DropDownOpened wird beim Öffnen der Liste ausgelöst, DropDownClosed bei deren Schließen.


Galileo Computing - Zum Seitenanfang

19.9.3 Das Steuerelement »ListView« Zur nächsten ÜberschriftZur vorigen Überschrift

Das Steuerelement ListView ähnelt nicht nur der ListBox, es ist sogar aus ListBox abgeleitet. Im Gegensatz zur ListBox kann ein ListView-Control die Einträge unterschiedlich darstellen. Was sich im ersten Moment noch positiv anhört, relativiert sich aber auch wieder, denn derzeit ist das nur mit einem GridView-Element direkt möglich. GridView ist aus ViewBase abgeleitet. Sie können auch eigene Darstellungsansichten durch das Ableiten von ViewBase ermöglichen, aber der Aufwand ist nicht unerheblich.

Sehen wir uns zur Veranschaulichung den einfachen Einsatz des ListView-Controls als einspaltiges Listenfeld in einem Codefragment an (siehe auch Abbildung 19.23):


<Grid>
  <ListView>
    <ListView.View>
      <GridView>
        <GridViewColumn Header="Name" />
      </GridView>
    </ListView.View>
    <ListViewItem>Peter Müller</ListViewItem>
    <ListViewItem>Franz Goldschmidt</ListViewItem>
    <ListViewItem>Rudi Ratlos</ListViewItem>
    <ListViewItem>Conie Serna</ListViewItem>
  </ListView>
</Grid>

Abbildung 19.23 Einfacher Einsatz des ListView-Controls

Die Beschreibung der Kopfzeile wird innerhalb des GridView-Elements mit GridViewColumn vorgenommen. Das GridView-Element seinerseits ist der Eigenschaft View des ListView-Controls zugeordnet. Für einfache Einträge reicht das ListViewItem-Element vollkommen aus.

Mehrspaltiges Listenfeld

Um in einer ListView eine Tabelle darzustellen, ist die Bindung an eine Datenquelle erforderlich. Mit der Datenbindung werden wir uns in Kapitel 21, »Datenbindung«, noch näher beschäftigen, daher sei sie an dieser Stelle nicht detailliert erklärt. Bei der Datenquelle muss es sich um ein Objekt handeln, das die Schnittstelle IEnumerable implementiert. Das Datenobjekt wird der Eigenschaft ItemSource des ListView zugewiesen.

Für jede Spalte ist ein GridViewColumn-Element zuständig. Wie im Beispiel zuvor gezeigt, wird mit der Eigenschaft Header die Beschriftung der Kopfzeile festgelegt. Die Eigenschaft DisplayMemberBinding bestimmt, welche Objekteigenschaft in der Spalte angezeigt wird.

Das folgende Beispielprogramm soll die Vorgehensweise demonstrieren. Dazu stellen wir uns zuerst einmal eine Datenquelle zur Verfügung. Diese soll aus mehreren Person-Objekten bestehen, die auf der folgenden Klassendefinition basieren:


class Person {
  public string Name { get; set; }
  public int Alter { get; set; }
  public string Wohnort { get; set; }
  public Person(string name, string ort, int alter) {
    Name = name;
    Alter = alter;
    Wohnort = ort;
  }
}

Eine Methode erzeugt mehrere Person-Objekte und liefert als Rückgabewert ein Objekt vom Typ List<Person> an den Aufrufer. Das ist die Liste, die uns als Datenquelle dienen soll.


private List<Person> CreatePersonListe() {
  List<Person> liste = new List<Person>();
  liste.Add(new Person("Müller", "Bonn", 56));
  ...
  return liste;
}

Für die Bindung der Datenquelle an die Eigenschaft ItemSource eignet sich der Konstruktor des Window-Objekts. Das ListView-Objekt soll den Namen lstView haben.


public MainWindow() {
  InitializeComponent();
  lstView.ItemsSource = CreatePersonListe();
}

Jetzt müssen wir nur noch den XAML-Code schreiben. Die Ausgabe des Beispiels sehen Sie in Abbildung 19.24.


// ------------------------------------------------------------------
// Beispiel: ...\Kapitel 19\ListViewSample
// ------------------------------------------------------------------
<Grid>
  <ListView Name="lstView">
    <ListView.View>
      <GridView>
        <GridView.Columns>
          <GridViewColumn Header="Name" Width="100" 
                          DisplayMemberBinding="{Binding Path=Name}" />
          <GridViewColumn Header="Wohnort" Width="100" 
                          DisplayMemberBinding="{Binding Path=Wohnort}" />
          <GridViewColumn Header="Alter" Width="80" 
                          DisplayMemberBinding="{Binding Path=Alter}" />
        </GridView.Columns>
      </GridView>
    </ListView.View>
  </ListView>    
</Grid>

Abbildung 19.24 Ausgabe des Beispielprogramms »ListViewSample«


Galileo Computing - Zum Seitenanfang

19.9.4 Das Steuerelement »TreeView« Zur nächsten ÜberschriftZur vorigen Überschrift

Mit diesem Steuerelement lassen sich Daten in hierarchischer Struktur darstellen. Sie kennen dieses Steuerelement, denn es wird auch im Windows-Explorer auf der linken Seite benutzt, um die Ordnerhierarchie dazustellen. Bei den Elementen eines TreeView-Controls handelt es sich nicht um eine lineare Liste, da jedes Element selbst wieder eine Liste untergeordneter Elemente haben kann.

Die Elemente werden durch den Typ TreeViewItem beschrieben. Die Eigenschaft Header dient zur Anzeige, ist selbst aber vom Typ Object. Die Eigenschaft Content gibt den Inhalt an.

Der folgende Code zeigt, wie die Elemente ineinander verschachtelt werden. In Abbildung 19.25 ist die Ausgabe des Codes zu sehen, wobei alle Knoten geöffnet sind.


<Grid>
  <TreeView Name="treeView1">
    <TreeViewItem Header="Asien">
      <TreeViewItem Header="China" />
      <TreeViewItem Header="Vietnam" />
      <TreeViewItem Header="Philippinen" />
    </TreeViewItem>
    <TreeViewItem Header="Europa">
      <TreeViewItem Header="Deutschland">
        <TreeViewItem Header="NRW" />
        <TreeViewItem Header="Hessen" />
      </TreeViewItem>
      <TreeViewItem Header="Italien" />
      <TreeViewItem Header="Österreich" />
    </TreeViewItem>
  </TreeView>
</Grid>

Abbildung 19.25 Das TreeView-Steuerelement


Galileo Computing - Zum Seitenanfang

19.9.5 Das Steuerelement »TabControl« Zur nächsten ÜberschriftZur vorigen Überschrift

In vielen Anwendungen werden gruppierte Inhalte durch TabControl-Steuerelemente dargestellt. Das entsprechende WPF-Steuerelement ist erstaunlich einfach zu erstellen.

Jede Registerkarte wird durch ein TabItem-Element beschrieben. Die Beschriftung wird mit der Eigenschaft Header festgelegt. Zur Darstellung des Inhalts dient die Eigenschaft Content, die genau ein Element aufnehmen kann. Wie Sie aber wissen, kann es sich dabei um ein Container-Steuerelement handeln, sodass der Gestaltung des Registerkarteninhalts keine Grenzen gesetzt sind.

Meist sind die Registerkarten oben angeordnet. Mit der Eigenschaft TabStripPlacement ist es möglich, diese auch links, rechts oder unten anzuordnen. Soll die Beschriftung dabei auch noch entsprechend gedreht werden, bietet sich die Eigenschaft LayoutTransform an, der mit RotateTransform ein Element untergeordnet wird, das den Drehwinkel im Uhrzeigersinn beschreibt.

Das folgende Codefragment zeigt ein TabControl, dessen Tabs rechts angeordnet sind. Die Beschriftung der einzelnen Tabs ist um 90° gedreht.


<Grid>
  <TabControl TabStripPlacement="Right">
    <TabItem Header="Tab 1" Height="30">
      <TabItem.LayoutTransform>
        <RotateTransform Angle="90" />
      </TabItem.LayoutTransform>
      <TabItem.Content>
        Hier steht der Inhalt der 1. Registerkarte.
      </TabItem.Content>
    </TabItem>
    <TabItem Header="Tab 2">
      <TabItem.LayoutTransform>
        <RotateTransform Angle="90" />
      </TabItem.LayoutTransform>
      <TabItem.Content>
        Hier steht der Inhalt der 2. Registerkarte.
      </TabItem.Content>
    </TabItem>
    <TabItem Header="Tab 3">
      <TabItem.LayoutTransform>
        <RotateTransform Angle="90" />
      </TabItem.LayoutTransform>
      <TabItem.Content>
        Hier steht der Inhalt der 3. Registerkarte.
      </TabItem.Content>
    </TabItem>
  </TabControl>
</Grid>

Abbildung 19.26 Das Steuerelement »TabControl«


Galileo Computing - Zum Seitenanfang

19.9.6 Menüleisten Zur nächsten ÜberschriftZur vorigen Überschrift

Bisher haben wir uns mit den wichtigsten Steuerelementen beschäftigt, die relativ einfach zu erstellen sind. Es ist nun an der Zeit, uns mit einem etwas komplexeren Steuerelement auseinanderzusetzen – mit der Menüleiste.

Die Menüleiste wird durch die Klasse Menu beschrieben, die untergeordneten Menüpunkte durch MenuItem. Trennstriche werden durch Separator beschrieben. Die Struktur eines Menüs sehen wir uns am besten an einem Beispiel an.


<DockPanel>
  <Menu DockPanel.Dock="Top" Name="mnuMenu">
    <MenuItem Header="_Datei">
      <MenuItem Header="_Neu" />
      <MenuItem Header="_Öffnen" />
      <Separator />
      <MenuItem Header="_Speichern" />
      <MenuItem Header="Speichern _unter ..." />
      <Separator />
      <MenuItem Header="_Senden an">
        <MenuItem Header="_Mail" />
        <MenuItem Header="_Desktop" />
      </MenuItem>
      <MenuItem Header="_Beenden" />
    </MenuItem>
    <MenuItem Header="_Bearbeiten" />
    <MenuItem Header="_Hilfe" />
  </Menu>
  <StackPanel>
  </StackPanel>
</DockPanel>

Menüs werden meistens oben am Rand des Arbeitsbereichs des Windows verankert. Dazu bietet sich das DockPanel an. Im Menü selbst wird die Eigenschaft DockPanel.Dock auf Top festgelegt. Um den verbleibenden Bereich auszufüllen, ist im Code nach Menu noch ein StackPanel aufgeführt.

In der ersten dem Menu-Steuerelement untergeordneten Ebene sind alle Elemente des Hauptmenüs aufgeführt. Diese sind vom Typ MenuItem. Jedes MenuItem kann für sich wieder eine ihm selbst untergeordnete Ebene eröffnen. Eingeschlossen wird eine Ebene jeweils zwischen dem öffnenden und dem schließenden Tag von MenuItem. Die Beschriftung der Menüelemente erfolgt mit der Eigenschaft Header. Wie bei anderen Steuerelementen auch kann mit einem Unterstrich ein Access-Key festgelegt werden. In Abbildung 19.27 sehen Sie die Ausgabe des XAML-Codes.

Abbildung 19.27 Ein Menü mit Untermenü in einem »Window«

Zur Programmierung eines Menüelements ist nicht viel zu sagen. Hier handelt es sich wieder um das Ereignis Click, das ausgelöst wird, wenn ein Anwender auf das Menüelement klickt.

Weitere Möglichkeiten der Menüleiste

Die Klasse MenuItem stellt mit vielen Eigenschaften Möglichkeiten zur Verfügung, um Einfluss auf das Layout auszuüben. Vier davon sollen an dieser Stelle vorgestellt werden.


Tabelle 19.12 Eigenschaften der Klasse »MenuItem«

Eigenschaft Beschreibung
Icon

Legt das Symbol fest, das in einem MenuItem angezeigt wird.

IsCheckable

Gibt an, ob ein MenuItem aktiviert werden kann.

IsChecked

Gibt an, ob das MenuItem aktiviert ist.

InputGestureText

Beschreibt die Tastenkombination.


Symbole anzeigen

Um einem Menüelement ein Symbol zuzuordnen, können Sie über die Eigenschaft Icon ein Bild zuordnen. Benutzen Sie dazu ein Image-Element, und geben Sie dessen Attribut Source die Position zu einer Bilddatei an. Im folgenden Codeabschnitt sehen Sie die Ergänzung der oben gezeigten Menüleiste um zwei Symbole:


<DockPanel>
  <Menu DockPanel.Dock="Top" Name="mnuMenu">
    <MenuItem Header="_Datei">
      <MenuItem Header="_Neu" />
      <MenuItem Header="_Öffnen">
        <MenuItem.Icon>
          <Image Source="Images/openHS.png" />
        </MenuItem.Icon>
      </MenuItem>
      <Separator />
      <MenuItem Header="_Speichern">
        <MenuItem.Icon>
          <Image Source="Images/saveHS.png" />
        </MenuItem.Icon>
      </MenuItem>
...

Tastenkürzel

Tastenkürzel mit der Taste Alt -Taste werden durch einen Unterstrich kenntlich gemacht. Um einen Shortcut zu verwenden, müssen Sie diese Angabe über die Eigenschaft InputGestureText zuweisen:


<MenuItem Header="_Öffnen" InputGestureText="Strg+O">
  <MenuItem.Icon>
    <Image Source="Images/openHS.png" />
  </MenuItem.Icon>
</MenuItem>

Abbildung 19.28 Untermenü mit Symbolen und Shortcuts

Aktivierbare Menüelemente

Manche Menüelemente sind Ein/Aus-Schaltern ähnlich. Sie signalisieren ihren augenblicklichen Zustand durch ein Häkchen. Die Voraussetzung für dieses Verhalten in einem WPF-Menü wird durch die Eigenschaft IsCheckable geschaffen. Mit IsChecked können Sie darüber hinaus festlegen, ob die Option des Menüelements ausgewählt ist oder nicht.


<MenuItem Header="Schriftstil">
  <MenuItem Header="Fett" IsCheckable="True" IsChecked="True" />
  <MenuItem Header="Kursiv" IsCheckable="True" IsChecked="False" />
</MenuItem>

Um ein Menüelement zu aktivieren bzw. zu deaktivieren, dient die Eigenschaft IsEnabled. Legen Sie diese auf False fest, um das Menüelement zu deaktivieren.


Hinweis

Den Code zu der hier gezeigten Menüleiste finden Sie auf der Buch-DVD unter ...\Beispiele\Kapitel 19\Menüleiste.



Galileo Computing - Zum Seitenanfang

19.9.7 Kontextmenüs Zur nächsten ÜberschriftZur vorigen Überschrift

Kontextmenüs ähneln der eben vorgestellten Menüleiste. Im einfachsten Fall wird ein Kontextmenü direkt einem Steuerelement zugeordnet. Die Zuordnung erfolgt mit der Eigenschaft ContextMenu des betreffenden Steuerelements. Im folgenden Beispiel wird das Kontextmenü eines Buttons entwickelt:


<Button Name="Button1" Height="25" Content="Kontextdemo">
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Name="cMenu1" Header="Kopieren" />         
      <MenuItem Name="cMenu2" Header="Ausschneiden" />
      <MenuItem Name="cMenu3" Header="Einfügen" />
    </ContextMenu>
  </Button.ContextMenu>
</Button>

Jedes Menüelement wird, wie auch bei der Menüleiste, durch ein Objekt vom Typ MenuItem beschrieben. Mit der Eigenschaft Header wird die Beschriftung festgelegt.

Häufig wird ein Kontextmenü von mehreren Steuerelementen gleichermaßen benutzt. Sie sollten die Definition des Kontextmenüs dann an einem allgemeinen Ort beschreiben. Hier bietet sich der Resources-Abschnitt des Window oder der Anwendung an. Um ContextMenu eindeutig einem bestimmten Steuerelement zuordnen zu können, muss ein key festgelegt werden, über den das Steuerelement sein zugeordnetes ContextMenu-Element identifizieren kann.


<Window ...>
  <Window.Resources>
    <ContextMenu x:Key="contextMenu1">
      <MenuItem Header="_Ausschneiden">
        <MenuItem.Icon>
          <Image Source="Images/CutHS.png" Height="16" Width="16" />
        </MenuItem.Icon>
      </MenuItem>
      <MenuItem Header="_Kopieren">
        <MenuItem.Icon>
          <Image Source="Images/CopyHS.png" Height="16" Width="16" />
        </MenuItem.Icon>
      </MenuItem>
      <MenuItem Header="_Einfügen" Click="Event_EditPaste">
        <MenuItem.Icon>
          <Image Source="Images/PasteHS.png" Height="16" Width="16" />
        </MenuItem.Icon>
      </MenuItem>
  </ContextMenu>
</Window.Resources>

Die Zuordnung des im Resources-Abschnitt definierten Kontextmenüs erfolgt durch Zuweisung als statische Ressource an die Eigenschaft ContextMenu des Steuerelements. Im nächsten Kapitel werden die Ressourcen thematisiert, sodass an dieser Stelle keine nähere Erklärung folgt.

Das Kontextmenü kann mithilfe der Klasse ContextMenuService hinsichtlich Verhalten, Positionierung und Layout beeinflusst werden. Die Eigenschaft HasDropShadow legt beispielsweise fest, ob das Kontextmenü einen Schatteneffekt zeigen soll, und Placement bestimmt, wo das Kontextmenü erscheinen soll. Mit HorizontalOffset und VerticalOffset können Sie festlegen, wo das Kontextmenü relativ zu seinem Steuerelement angezeigt werden soll.

Der folgende XAML-Code zeigt die Einbindung des im Resources-Abschnitt definierten Kontextmenüs. Hier wird eine TextBox als Elternelement festgelegt und zudem demonstriert, wie ContextMenuService zur spezifischen Beschreibung eingesetzt wird.


<DockPanel>   
  <TextBox ContextMenu="{StaticResource ResourceKey=contextMenu1}" 
           ContextMenuService.HasDropShadow="True" 
           ContextMenuService.Placement="Mouse" />    
</DockPanel>


Galileo Computing - Zum Seitenanfang

19.9.8 Symbolleisten Zur nächsten ÜberschriftZur vorigen Überschrift

Auch wenn es zunächst den Anschein haben mag, dass Symbolleisten zu den komplexen WPF-Steuerelementen zu rechnen sind, ist dem nicht so. Eigentlich handelt es sich dabei nur um einen Container, der andere Controls beherbergt. Symbolleisten werden durch das Element ToolBar beschrieben. Eine ToolBar kann beliebige andere Steuerelemente aufnehmen und darstellen, aber in der Regel wird es sich dabei um Elemente vom Typ Button handeln.

Üblicherweise wird eine Symbolleiste unterhalb der Menüleiste angedockt. Als Container wird daher ein DockPanel eingesetzt, das Menu als erstes Element oben angedockt, und danach folgt die Symbolleiste.


<DockPanel>
  <Menu DockPanel.Dock="Top" Name="mnuMenu">
  </Menu>
  <ToolBar DockPanel.Dock="Top" Height="30">
    <Button>
      <Image Source="Images/openHS.png" />
    </Button>
    <Button>
      <Image Source="Images/saveHS.png" />
    </Button>
    <Separator />
    <ComboBox Width="80" SelectedIndex="0">
      <ComboBoxItem>Arial</ComboBoxItem>
      <ComboBoxItem>Courier</ComboBoxItem>
      <ComboBoxItem>Windings</ComboBoxItem>
    </ComboBox>
  </ToolBar>
    <StackPanel>
    </StackPanel>
</DockPanel>

Beim Verkleinern des Fensters könnte es passieren, dass die Fensterbreite nicht mehr ausreicht, um alle in einer ToolBar enthaltenen Komponenten anzuzeigen. Es wird dann ein Überlaufbereich erzeugt, an dessen Ende eine Schaltfläche mit einem Pfeil angezeigt wird. Über diese Schaltfläche lässt sich ein Menü aufklappen, in dem die nicht mehr darstellbaren Elemente angezeigt werden können.

Einzelnen Steuerelementen kann das Überlaufverhalten vorgeschrieben werden. Dazu wird der zugeordneten Eigenschaft OverflowMode ein Wert der gleichnamigen Enumeration übergeben.


Tabelle 19.13 Mitglieder der Enumeration »OverflowMode«

Member Beschreibung
Always

Das Steuerelement wird immer im Überlaufbereich angezeigt.

AsNeeded

Das Steuerelement wird bei Bedarf im Überlaufbereich angezeigt.

Never

Das Steuerelement wird nie im Überlaufbereich angezeigt.


Der folgende Code beschreibt eine Symbolleiste mit drei ComboBoxen. Jeder ist eine andere Einstellung der Eigenschaft OverflowMode zugewiesen.


<ToolBar Height="30">
  <Button>
    <Image Source="Images/openHS.png" />
  </Button>
  <Button>
    <Image Source="Images/saveHS.png" />
  </Button>
  <Separator />
  <ComboBox Width="80" SelectedIndex="0" 
            ToolBar.OverflowMode="Always">
    <ComboBoxItem>Arial</ComboBoxItem>
    <ComboBoxItem>Courier</ComboBoxItem>
    <ComboBoxItem>Windings</ComboBoxItem>
  </ComboBox>
  <ComboBox Width="80" SelectedIndex="0" 
            ToolBar.OverflowMode="AsNeeded">
    <ComboBoxItem>Bonn</ComboBoxItem>
    <ComboBoxItem>München</ComboBoxItem>
    <ComboBoxItem>Nürnberg</ComboBoxItem>
  </ComboBox>
  <ComboBox Width="80" SelectedIndex="0" 
            ToolBar.OverflowMode="Never">
    <ComboBoxItem>Test1</ComboBoxItem>
    <ComboBoxItem>Test2</ComboBoxItem>
    <ComboBoxItem>Test3</ComboBoxItem>
  </ComboBox>
</ToolBar>

In Abbildung 19.29 sind die Auswirkungen deutlich zu sehen. Das Kombinationslistenfeld mit der Einstellung OverflowMode=Always ist auch dann nur über die Dropdown-Schaltfläche in der Symbolleiste zu erreichen, wenn die Breite der Form eigentlich zur Darstellung ausreichen würde. Wird die Fensterbreite verringert, wird nur noch die ComboBox in der Symbolleiste angezeigt, deren Einstellung OverflowMode=Never lautet.

Abbildung 19.29 Der Einfluss der Eigenschaft »OverflowMode«

Positionieren mit der Komponente »ToolBarTray«

Möchten Sie mehrere ToolBars in einer Form anzeigen, bietet sich die Komponente ToolBarTray an. Dabei handelt es sich um einen Container, der das Positionieren aller enthaltenen ToolBars steuert. Mit einer ToolBarTray-Komponente wird es möglich, Symbolleisten hintereinander oder in mehreren Reihen anzuzeigen und mittels Drag&Drop zu verschieben.

Zu diesem Zweck stellt das ToolBar-Steuerelement mit Band und BandIndex zwei Eigenschaften zur Verfügung, die sich auf die Positionierung im ToolBarTray auswirken. Mit Band geben Sie an, in welcher Zeile die ToolBar erscheinen soll. Mit BandIndex legen Sie deren Position innerhalb der Zeile fest, wenn die Zeile von mehreren ToolBars in Anspruch genommen wird.


<ToolBarTray DockPanel.Dock="Top" IsLocked="False">
  <ToolBar Height="30" Band="0" BandIndex="0">
    ...
  </ToolBar>
  <ToolBar Height="30" Band="0" BandIndex="1" >
    ...
  </ToolBar>
  <ToolBar Height="30" Band="1" Band="0">
    ...
  </ToolBar>
  <ToolBar Height="30" Band="1" BandIndex="1" >
    ...
  </ToolBar>
</ToolBarTray>

Die Einstellungen wirken sich auf die Darstellung der ToolBars nach dem Starten des Fensters aus. Zur Laufzeit kann der Anwender die Position nach Belieben mittels Drag&Drop verändern.

Abbildung 19.30 Zwei Symbolleisten in der Komponente »ToolBarTray«


Galileo Computing - Zum Seitenanfang

19.9.9 Die Statusleiste topZur vorigen Überschrift

Die meist unten im Window angezeigten Statusleisten informieren den Anwender über den Zustand des laufenden Programms. WPF stellt Ihnen mit StatusBar eine Komponente zur Verfügung, mit der Sie das realisieren können.

Sie können in die StatusBar beliebige Komponenten einfügen, z. B. TextBox oder Label. Besser ist es allerdings, stattdessen mit StatusBarItem-Elementen Bereiche zu definieren, in denen die Komponenten eingebettet sind. Das ermöglicht es Ihnen, die Ausrichtung der Komponenten einfach zu gestalten. Dazu bietet sich die Eigenschaft HorizontalAlignment oder auch VerticalAlignment an.


<DockPanel>
  <Menu DockPanel.Dock="Top" Name="mnuMenu">
  ...
  </Menu>
  <ToolBarTray DockPanel.Dock="Top" IsLocked="False">
    <ToolBar Height="30" BandIndex="0" Band="0">
      ...
    </ToolBar>
  </ToolBarTray>
  <StatusBar DockPanel.Dock="Bottom" Height="30">
    <Button Width="80">Start</Button>
    <Label>Suchen:</Label>
    <StatusBarItem Width="100" 
           HorizontalContentAlignment="Stretch"> 
     <TextBox>Suchbegriff</TextBox>
    </StatusBarItem>
    <Separator />
    <StatusBarItem HorizontalAlignment="Right">
           Anzahl: 2</StatusBarItem>
  </StatusBar>
  <StackPanel>
  </StackPanel>
</DockPanel>

Abbildung 19.31 Window mit Statusleiste



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2010

Visual C# 2010
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: C/C++






 C/C++


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2010
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern