Entwicklung eines benutzerdefinierten Steuerelements unter Verwendung von XAML und C#

Entwicklerblog für Windows 8-Apps

Ein Einblick in die Entwicklung von Apps im Metro-Stil – präsentiert vom Windows 8-Entwicklerteam

Entwicklung eines benutzerdefinierten Steuerelements unter Verwendung von XAML und C#

Rate This
  • Comments 0

Möglicherweise wissen Sie bereits, dass die Flexibilität, die die Windows 8 XAML-Plattform für die Entwicklung benutzerdefinierter Steuerelemente bereitstellt, eines ihrer stärksten Merkmale ist. XAML stellt Ihnen Funktionen wie Abhängigkeitseigenschaften und Steuerelementvorlagen zur Verfügung, mit denen die Entwicklung funktionsreicher und benutzerdefinierbarer Steuerelemente leicht von der Hand geht.

Im vorhergehenden Blogbeitrag Entwicklung eines benutzerdefinierten Steuerelements unter Verwendung der Windows-Bibliothek für JavaScript führte Jordan Matthiesen Sie Schritt für Schritt durch die Entwicklung eines benutzerdefinierten HelloWorld-Steuerelements. In diesem Beitrag führe ich Sie durch die Entwicklung desselben Steuerelements in XAML. Ich stelle Techniken und Konzepte vor, mit denen Sie wiederverwendbare benutzerdefinierte Steuerelemente entwickeln können, und zeige Ihnen, wie Sie eine Vorlage zum Entwerfen dieser Steuerelemente erstellen. Ich erläutere Konzepte wie Abhängigkeitseigenschaften und die Verwendung einer benutzerdefinierten Generic.xaml-Datei zum Erstellen eines impliziten Stils, der eine Standard-Vorlage für Steuerelemente definiert.

Ein einfaches XAML-Steuerelement

Zunächst erstellen wir das „Hello World“-Steuerelement: eine aus Windows.UI.XAML.Controls.Control abgeleitete Klasse. Erstellen Sie in Visual Studio mithilfe der Vorlage „Leeres Projekt“ ein neues Projekt. Nennen Sie Ihr Projekt CustomControls. Fügen Sie Ihr benutzerdefiniertes Steuerelement mithilfe des Vorlage-Assistenten „Neues Element“ hinzu.

Visual Studio enthält eine Elementvorlage für Steuerelemente mit Vorlagen. Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie „Hinzufügen -> Neues Element“ aus

Visual Studio enthält eine Elementvorlage für ein Steuerelement mit Vorlagen. Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie „Hinzufügen -> Neues Element“ aus

Die Elementvorlage für ein Steuerelement mit Vorlagen erstellt die Dateien und ein Code-Gerüst, mit dem das benutzerdefinierte Steuerelement gestartet werden kann

Wählen Sie das Element Steuerelement mit Vorlagen aus und nennen Sie das Steuerelement „HelloWorld.cs“.

Diese Vorlage erstellt folgende Klasse:

public class HelloWorld : Control
{
public HelloWorld() {
this.DefaultStyleKey = typeof(HelloWorld);
}
}

In diesem kurzen Codeblock werden zwei sehr wichtige Details angegeben. Erstens, dass die Klasse „HelloWorld“ von „Control“ abgeleitet wird. Zweitens zeigt die Einstellung „DefaultStyleKey“ der XAML-Plattform an, dass diese Klasse einen impliziten Stil verwendet. Die Vorlage des Steuerelements mit Vorlagen fügt zudem einen „Themen“-Dateiordner hinzu und erstellt in diesem Ordner eine neue Datei namens „Generic.xaml“. Unter Projektvorlagen finden Sie weitere Informationen über diese Vorlage.

Der Standardstil eines Steuerelements wird in der benutzerdefinierten Datei „Generic.xaml“ definiert, die von der Plattform automatisch geladen wird. In dieser Datei wird ein impliziter Stil definiert. Dies bedeutet, dass wir einen Stil definieren können, der standardmäßig auf alle Steuerelemente eines bestimmten Typs angewendet wird. Fügen Sie den markierten XAML-Code der neuen Datei „Generic.xaml“ im Themenordner hinzu:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML"
xmlns:local="using:CustomControls">

<Style TargetType="local:HelloWorld">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:HelloWorld">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock Text="HelloWorld"
FontFamily="Segoe UI Light"
FontSize="36"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

Diese wenigen XAML-Zeilen definieren einen Stil, der standardmäßig auf alle Instanzen des „HelloWorld“-Steuerelements angewendet wird. Wir definieren eine Steuerelement-Vorlage, die angibt, dass es sich bei diesem Steuerelement einfach um einen Textblock mit dem Text „HelloWorld“ handelt.

Rufen Sie jetzt Ihre MainPage.xaml-Datei auf und fügen Sie das nächste Markup hinzu. Sie müssen die Bestimmung „local:“ einfügen, um XAML mitzuteilen, in welchem Namespace sich die HelloWorld-Klasse befindet. Die Bestimmung „local:“ wird am Anfang der XAML-Datei definiert.

<local:HelloWorld />

Wenn Sie die App ausführen, sehen Sie, dass das Steuerelement geladen wurde und den Text „Hello, World!” im Textkörper Ihrer Seite anzeigt.

Definieren der Optionen des Steuerelements

Wenn wir konfigurierbare Optionen hinzufügen, erhalten wir nützlichere, wiederverwendbare Steuerelemente. Lassen Sie uns eine Option hinzufügen, mit der wir das Steuerelement blinken lassen können.

Um diese Option hinzuzufügen, müssen wir dem Steuerelement eine Abhängigkeitseigenschaft (DP, Dependency Control) hinzufügen. Weitere Informationen über DPs finden Sie unter Übersicht über Abhängigkeitseigenschaften. Es gibt einen Visual Studio-Codeausschnitt, der das Hinzufügen von DPs stark vereinfacht. Führen Sie den Cursor unter den Konstruktor, geben Sie „propdp“ ein und drücken Sie zweimal auf die TAB-TASTE. Sie können die Spezifikationen ergänzen, indem Sie mithilfe des Tabulators alle Parameter im Ausschnitt ansteuern.

public class HelloWorld : Control
{
public HelloWorld() {
this.DefaultStyleKey = typeof(HelloWorld);
}

public bool Blink
{
get { return (bool)GetValue(BlinkProperty); }
set { SetValue(BlinkProperty, value); }
}

// Using a DependencyProperty enables animation, styling, binding, etc.
public static readonly DependencyProperty BlinkProperty =
DependencyProperty.Register(
"Blink", // The name of the DependencyProperty
typeof(bool), // The type of the DependencyProperty
typeof(HelloWorld), // The type of the owner of the DependencyProperty
new PropertyMetadata( // OnBlinkChanged will be called when Blink changes
false, // The default value of the DependencyProperty
new PropertyChangedCallback(OnBlinkChanged)
)
);

private DispatcherTimer __timer = null;
private DispatcherTimer _timer
{
get
{
if (__timer == null)
{
__timer = new DispatcherTimer();
__timer.Interval = new TimeSpan(0,0,0,0,500); // 500 ms interval
__timer.Tick += __timer_Tick;
}

return __timer;
}
}

private static void OnBlinkChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e
)
{
var instance = d as HelloWorld;
if (instance != null)
{
if (instance._timer.IsEnabled != instance.Blink)
{
if (instance.Blink)
{
instance._timer.Start();
}
else
{
instance._timer.Stop();
}
}
}
}

private void __timer_Tick(object sender, object e)
{
DoBlink();
}

private void DoBlink()
{
this.Opacity = (this.Opacity + 1) % 2;
}
}

Kehren Sie zu MainPage.xaml zurück und fügen Sie dem Steuerelement die Konfigurationsoption hinzu.

<local:HelloWorld Blink="True" />

Führen Sie die App aus und sehen Sie, wie das Steuerelement blinkt!

Unterstützung für Ereignisse hinzufügen

Sie können die Funktionalität steigern, indem Sie zu Steuerelementen Ereignisse hinzufügen. Ereignisse ermöglichen, dass Sie bei Aktionen vom Steuerelement Unterbrechungen erhalten, sodass Sie dann Code ausführen können, der auf diese Aktionen antwortet. Lassen Sie uns ein Ereignis hinzufügen, welches jedesmal auslöst, wenn das Steuerelement blinkt.

public class HelloWorld : Control
{

...
...
private void __timer_Tick(object sender, object e)
{
DoBlink();
}

private void DoBlink()
{
this.Opacity = (this.Opacity + 1) % 2;
OnBlinked();
}

public event EventHandler Blinked;

private void OnBlinked()
{
EventHandler eh = Blinked;
if (eh != null)
{
eh(this, new EventArgs());
}
}
}

Kehren Sie zu MainPage.xaml zurück und fügen Sie dem Element eine x:Name-Eigenschaft hinzu, sodass wir die Steuerelementinstanz später als Code abrufen können:

<local:HelloWorld x:Name="HelloWorldWithEvents" Blink="True" />

Fügen Sie in MainPage.xaml.cs einen Ereignislistener-Funktionsdelegaten zum Ausdrucken der Debug-Ausgabe beim Auslösen des Ereignisses hinzu.

HelloWorldWithEvents.Blinked += (object sender, EventArgs args) =>
{
System.Diagnostics.Debug.WriteLine("HelloWorldWithEvents Blinked");
};

Wenn Sie diesen Code ausführen, sehen Sie eine Benachrichtigung, die alle 500 Millisekunden an das Ausgabekonsolenfenster in Visual Studio ausgegeben wird.

Verfügbarmachen von öffentlichen Methoden

Wir haben bereits die private Methode „DoBlink“ geschrieben, um das Steuerelement blinken zu lassen. Nun ändern wir diese Methode in „public“, sodass das Steuerelement jederzeit blinken kann. Sie müssen nur noch die Sichtbarkeit der DoBlink-Methode in „public“ ändern:

public class HelloWorld : Control
{
...

public void DoBlink()
{
this.Opacity = (this.Opacity + 1) % 2;
OnBlinked();
}

...
}

Jetzt können Sie die öffentliche DoBlink-Methode in C#-Hintergrundcode aufrufen, etwa in einem Handler für Klicks auf die Schaltfläche.

private void Button_Click_1(object sender, RoutedEventArgs e)
{
HelloWorldWithEvents.DoBlink();
}

Wiederverwenden von Steuerelementen

Wenn Sie ein Steuerelement nur in einem einzigen Projekt oder nur selbst verwenden möchten, müssen Sie über Verpackung und Verteilung nicht weiter nachdenken. Wenn Sie jedoch ein wiederverwendbares Steuerelement entwickeln und mit anderen Entwicklern teilen möchten, haben Sie mehrere Möglichkeiten. Eine Möglichkeit ist das Erstellen eines Visual Studio-Erweiterungs-SDKs, das andere Entwickler auf ihren Computern installieren und zu ihren Projekten hinzufügen können. Weitere Informationen hierzu finden Sie unter Erstellen eines SDK mit C#.

Zusammenfassung

Wir haben nun die wichtigsten Aspekte beim Implementieren eines Steuerelements kennengelernt:

  1. Das Steuerelement in eine Webseite einfügen
  2. Konfigurationsoptionen übergeben
  3. Verteilen und Reagieren auf Ereignisse
  4. Verfügbarmachen von Funktionen über öffentliche Methoden

Sie kennen nun die Grundlagen über benutzerdefinierte XAML-Steuerelemente. Der nächste Schritt besteht darin, nach Funktionen zu suchen, die einem vorhandenen XAML-Steuerelement hinzugefügt werden sollen, und entweder den Stil zu ändern oder das Steuerelement zu einer Unterklasse zu machen, um Ihre eigenen Funktionen hinzuzufügen. Je besser Sie mit benutzerdefinierten Steuerelementen vertraut sind, desto leichter wird Ihnen das Schreiben von XAML-Apps fallen. Experimentieren Sie nun mit Ihren eigenen benutzerdefinierten Steuerelementen, ich freue mich auf Ihre Onlinebeiträge zu Ihren Erfahrungen.

Ich hoffe, dieser Beitrag war hilfreich für Sie! Sollten bei der Arbeit an Ihren Steuerelementen weitere Fragen auftreten, besuchen Sie das Windows-Entwicklungscenter und stellen Sie sie in den Foren.

– Aaron Wroblewski
Program Manager, Windows

  • Loading...
Leave a Comment
  • Please add 4 and 5 and type the answer here:
  • Post