Einfache Silverlight-Anwendung: Hallo Welt (erweitert)

Einfache Silverlight-Anwendung: Hallo Welt (erweitert)

Eine Erweiterung der hier erzeugten Applikation.

Die 2. Textbox wird mehrzeilig gemacht. Anschließend werfen wir einen kurzen Blick auf die interne Organisation einer Silverlight Anwendung.

Voraussetzungen: Visual Studio 2010 in beliebiger Version mit installierten Silverlight 4 Tools for Visual Studio 2010.

Das Ändern der 2. Textbox (textBox2) in eine mehrzeilige Textbox ist einfach. Zunächst (nachdem wir das Projekt aus dem letzten Artikel geöffnet haben) selektieren wir in der Designansicht die untere Textbox. Anschließend suchen wir im Properties-Fenster.. nicht etwas multiline oder etwas anderes, was man erwarten könnte.. sondern AcceptsReturn, welches wir am einfachsten über die Suchfunktion finden. Diese Option wählen wir aus. AcceptsReturn gibt uns bereits einen Hinweis darauf, dass der Zeilenumbruch nicht automatisch generiert wird, hier müssen wir also nochmal in der Code-Behind Datei Hand anlegen und die Funktion ändern, die ausgeführt wird,wenn Button1 geklickt wird.

1
2
3
4
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            textBox2.Text = "Hallo " + textBox1.Text + "," + Environment.NewLine + "was für ein schöner Tag";
        }

Nun können wir uns über den gesamten Text in der Applikation freuen.

Als nächstes wollen wir uns anschaun, wie Elemente der Oberfläche intern dargestellt werden. Einen sehr guten Anhaltspunkt bietet uns hier bereits der XAML Code, den wir erstellt haben.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<userControl x:Class="SilverlightHelloWorld.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
 
    <grid x:Name="LayoutRoot">
        <textBox Height="49" HorizontalAlignment="Left" Margin="124,26,0,0" Name="textBox1" VerticalAlignment="Top" Width="213" GotFocus="textBox1_GotFocus" />
        <button Content="Grüßen" Height="42" HorizontalAlignment="Left" Margin="124,99,0,0" Name="button1" VerticalAlignment="Top" Width="213" Click="button1_Click" />
        <textBox Height="42" HorizontalAlignment="Left" Margin="124,162,0,0" Name="textBox2" VerticalAlignment="Top" Width="213" IsReadOnly="True" AcceptsReturn="True" />
        <sdk:Label Height="22" HorizontalAlignment="Left" Margin="79,39,0,0" Name="label1" VerticalAlignment="Top" Width="39" Content="Name" />
        <grid.Background>
            <linearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <gradientStop Color="#FF246724" Offset="0" />
                <gradientStop Color="#FFFC6464" Offset="1" />
                <gradientStop Color="#FF26C61E" Offset="0.123" />
                <gradientStop Color="#FF1B948F" Offset="0.369" />
                <gradientStop Color="#FF2442BC" Offset="0.533" />
                <gradientStop Color="#FF4B00FA" Offset="0.803" />
            </linearGradientBrush>
        </grid.Background>
    </grid>
</userControl>

Wer bereits mit anderen Technologien wie MFC oder WinForms gearbeitet hat wird Parallelen erkennen: es gibt ein Hauptfenster, in dem verschiedene Elemente angeordnet sind, die wiederum neue Elemente enthalten können.

In unserem Fall gibt es z. B. (in der Hierarchie) direkt unter dem Hauptfenster ein Gridcontrol, das es uns erlaubt, Elemente in einem Gitter anzuordnen. Gäbe es hier gar keine Vorgaben wüßte Silverlight nicht, wo es Controls ohne explizite Ortsangabe einfügen sollte.

Neben dem Grid-Control gibt es insbesondere noch das Stackpanel, das noch einfacher ist: hier werden Controls jeweils entweder horizontal oder vertikal nebeneinander angeordnet.

Natürlich gibt es auch noch die Möglichkeit, Controls über die Margin, den Abstand zu den verschiedenen Seiten, kombiniert mit dem Alignment, d. h. die Abstände zu welchen Seiten dann auch tatsächlich herangezogen werden, zu positionieren. Oft läßt sich über eine Vermischung der Positioniermöglichkeiten das gewünschte Verhalten auch bei unterschiedlichen Größen des Fensters der ausgeführten Anwendung erreichen.

Als nächste erweitern wie die Anwendung um ein Stackpanel, und zwar fügen wir dieses im XAML zwischen dem Label ein, das wir zuletzt hinzugefügt haben und dem Grid.Background Tag.

1
2
3
4
        <stackPanel Height="46" Orientation="Horizontal" HorizontalAlignment="Left" Margin="124,223,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="213">
            <ellipse Height="32" Name="ellipse1" Stroke="Black" StrokeThickness="1" Width="74" />
            <slider Height="23" Name="slider1" Width="100" />
        </stackPanel>

Wenn wir die Elemente per Drag and Drop über die Toolbox hinzufügen müssen wir noch die Anordnung der Elemente innerhalb des StackPanels anpassen, indem wir die Orientation auf Horizontal setzen.

Um uns den internen Aufbau dieser Anwendung anschaun zu können, vergrößern wir zunächst die Design-Größe des Fenster in der Weite auf 600 Pixel durch Ändern des d:DeisgnWidth Wertes. Dieser Wert hat ausschließlich Auswirkungen auf die Größe des Fensters im Design Modus, also insbesondere keine Auswirkung auf die Größe zur Laufzeit. Diese bestimmen wir typischerweise über das einbettende .html Dokument.

1
    d:DesignHeight="300" d:DesignWidth="600" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

Anschließend fügen wir im XAML hinter dem StackPanel noch einen TreeView ein:

1
        <sdk:TreeView Height="242" HorizontalAlignment="Left" Margin="364,26,0,0" Name="treeView1" VerticalAlignment="Top" Width="209" />

Dieses TreeView Control füllen wir nun mit der Struktur der Oberfläche: mit den intern erzeugten Oberflächenelementen. Da diese ähnlich verschachtelt aussehen wie der XAML Code wählen wir eine Baumdarstellung.

Zunächst fügen wir in der Klasse MainPage eine Funktion iterate hinzu. Diese benötigt zwei Argumente:

  • einen Parameter über einen Knoten der Oberfläche, über den Informationen gefunden werden sollen
  • einen Parameter, wo die gefundenen Informationen im Baum eingefügt werden
1
2
3
4
5
6
7
8
9
10
11
12
        private void iterate(DependencyObject depObj, ItemCollection parentItems)
        {
            TreeViewItem tvi = new TreeViewItem();
            tvi.Header = depObj.ToString();
            int children = VisualTreeHelper.GetChildrenCount(depObj);
            for (int i = 0; i < children; ++i)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                iterate(child, tvi.Items);
            }
            parentItems.Add(tvi);
        }

Zunächst erzeugen wir ein neues TreeViewItem in Zeile 3, dieses fügen wir später in Zeile 11 an der aktuellen Stelle im Baum ein. Den Text dieses Items, tvi.Header, setzen wir auf die String-Räpresentation des aktuellen Elementes der Oberfläche, depObj. Anschließend iterieren wir über alle Kinder und rufen die Funktion rekursiv auf.

Wunderbar, nun müssen wir nur noch die richtigen Anfangsparameter für diese Funktion finden und diese aufrufen. Eine Möglichkeit hierfür bietet das Loaded-Event des äußersten Controls. Wenn wir in MainPage.xaml entweder außerhalb der Anwendung klicken oder auch im XAML Editor innerhalb des ersten UserControl klicken, erhalten wir im Properties Fenster die Möglichkeit, Events (auf Events klicken) für dieses Control mit Funktionalität zu füllen. Wir suchen das Loaded Event und doppelklicken rechts daneben in das leere Feld. Anschließend fügen wir noch folgenden Code in die Code-Behind Datei ein:

1
2
3
4
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            iterate(this, treeView1.Items);
        }

Wenn wir jetzt die Anwendung mit F5 starten sehen wir rechts im TreeView die intern generierte Struktur aus dem XAML Code. Und diese Struktur sieht dem Code verdammt ähnlich.

Wir halten also fest: typischerweise erzeugen wir im XAML beliebig tief verschachtelte Controls, um unserer Anwendung das gewünschte Aussehen zu geben.

One thought on “Einfache Silverlight-Anwendung: Hallo Welt (erweitert)

  1. Noch einfacher läßt sich die 2. Textbox mehrzeilig machen, indem man die TextWrapping Eigenschaft verwendet. Dort dann von NoWrap auf Wrap umstellen. (Nach TextWrapping in dem Eigenschaften Fenster suchen.)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.