Dieser Artikel wurde noch nicht bewertet - Dieses Thema bewerten.

Übersicht über Ereignisse und Routingereignisse (Windows Store-Apps mit C#/VB/C++ und XAML)

Wir beschreiben das Programmierkonzept von Ereignissen bei der Verwendung von C#, Visual Basic oder C++ als Programmiersprache und XAML für die UI-Definition. Sie können im Rahmen der Deklarationen für UI-Elemente Handler für Ereignisse im XAML zuweisen. Alternativ können Sie Handler mit sprachspezifischer Syntax im Code hinzufügen. Die Windows-Runtime unterstützt Routingereignisse. Dabei handelt es sich um ein Feature, bei dem bestimmte Eingabeereignisse und Datenereignisse von anderen Objekten behandelt werden können als dem Objekt, von dem das Ereignis ausgelöst wurde. Routingereignisse sind hilfreich, wenn Sie Steuerelementvorlagen definieren oder die Ereignislogik einer App-Seite oder eines Layoutcontainers zentralisieren.

Ereignisse als Programmierkonzept

Im Allgemeinen ist das Konzept der Ereignisse bei der Verwendung von C#, Microsoft Visual Basic oder C++ als Programmiersprache und von XAML für die UI-Definition mit dem Ereignismodell in Ihrer bevorzugten Programmiersprache vergleichbar. Wenn Sie bereits mit .NET-Ereignissen vertraut sind, kommen Sie sofort zurecht. Für verschiedene allgemeine Aufgaben, wie das Hinzufügen von Handlern, müssen Sie aber nicht allzu viel über das .NET-Ereignismodell wissen.

Wenn Sie C#, Visual Basic oder C++ als Programmiersprache verwenden, wird die UI im Markup (XAML) definiert. Bei der XAML-Markupsyntax ähneln einige der Prinzipien, nach denen UI-Ereignisse aus Markupelementen mit einer Laufzeit-Codeentität verbunden werden, denen anderer Webtechnologien (z. B. ASP.NET oder HTML5).

Der Code, der die Laufzeitlogik für eine mit XAML definierte UI bereitstellt, wird häufig CodeBehind oder CodeBehind-Datei genannt. In den Projektmappenansichten von Microsoft Visual Studio wird diese Beziehung grafisch dargestellt. Dabei ist die CodeBehind-Datei eine abhängige und geschachtelte Datei zu der XAML-Seite, auf die sie sich bezieht.

Button.Click: Einführung in Ereignisse und XAML

Zu den häufigsten Programmieraufgaben für eine Windows Store-App gehört es, Benutzereingaben für die UI zu erfassen. Beispielweise kann Ihre UI eine Schaltfläche enthalten, auf die der Benutzer klicken muss, um Informationen zu senden oder einen Zustand zu ändern.

Sie definieren die UI für Ihre Windows Store-App, indem Sie XAML generieren. Bei diesem XAML kann es sich um die Ausgabe eines Designers wie Microsoft Expression Blend oder einer Entwurfsoberfläche in Visual Studio handeln. Sie können das XAML auch in einem Nur-Text-Editor oder in einem XAML-Editor eines Drittanbieters schreiben. Beim Generieren dieses XAML können Sie Ereignishandler für einzelne UI-Elemente verknüpfen, während Sie gleichzeitig alle anderen XAML-Attribute definieren, die Eigenschaftswerte dieses UI-Elements einrichten.

Zur Ereignisverknüpfung in XAML gehört, dass Sie den Namen der Handlermethode, die Sie in Ihrem CodeBehind definieren, als Zeichenfolge angeben. Dieses XAML definiert beispielsweise ein Button-Objekt mit einigen wichtigen Eigenschaften, die als Attribute zugewiesen sind, und verknüpft einen Handler für das Click-Ereignis der Schaltfläche:


<Button x:Name="showUpdatesButton"
  Content="{Binding ShowUpdatesText}"
  Click="showUpdatesButton_Click"/>

Sie schreiben den Handler selbst in der von Ihnen gewählten Programmiersprache, beispielsweise in Visual Basic oder C#. Mit dem Attribut Click="showUpdatesButton_Click" haben Sie einen Vertrag erstellt, mit dem beim Kompilieren des Markups und Analysieren des XAML sowohl der XAML-Markupkompilierschritt in der Erstellungsaktion Ihrer Entwicklungsumgebung als auch der letztendliche XAML-Laufzeitanalysevorgang eine Methode mit dem Namen showUpdatesButton_Click finden können. showUpdatesButton_Click muss außerdem eine Methode darstellen, die eine kompatible Methodensignatur (basierend auf einem Delegaten) für jeden Handler des Click-Ereignisses implementiert. Dieser Code definiert z. B. denshowUpdatesButton_Click-Handler.


private void showUpdatesButton_Click (object sender, RoutedEventArgs e) {
    Button b = sender as Button;
    //more logic to do here...
...
}

Tipp  Visual Studio bietet eine bequeme Methode zum Benennen des Ereignishandlers und zum Definieren des Handlers über Microsoft IntelliSense. Wenn Sie den Attributnamen des Ereignisses im XAML-Text-Editor bereitstellen, warten Sie einen Moment, bis eine IntelliSense-Liste angezeigt wird. Wenn Sie in der Liste auf <Neuer Ereignishandler> klicken, schlägt Microsoft Visual Studio einen Methodennamen vor, der auf dem x:Name des Elements (oder der Typbezeichnung), dem Ereignisnamen und einem numerischen Suffix basiert. Anschließend können Sie mit der rechten Maustaste auf den ausgewählten Ereignishandler und dann mit der linken Maustaste auf Zum Ereignishandler navigieren klicken. Dadurch navigieren Sie direkt zu der neu eingefügten Ereignishandlerdefinition, wie sie im Code-Editor angezeigt wird. Der Ereignishandler hat bereits die richtige Signatur, einschließlich des sender-Parameters und der jeweiligen Ereignisdatenklasse, die von dem Ereignis verwendet wird. Wenn zudem bereits eine Handlermethode mit der richtigen Signatur im CodeBehind vorhanden ist, wird der Name dieser Methode zusammen mit der Option <Neuer Ereignishandler> im Auto-Vervollständigen-Dropdown angezeigt. Sie können auch die Tabulatortaste drücken, anstatt auf die IntelliSense-Listenelemente zu klicken.

Definieren eines Ereignishandlers

Für Objekte, die UI-Elemente darstellen und in XAML deklariert werden, muss Ereignishandlercode in der partiellen Klasse definiert werden, die als CodeBehind für eine XAML-Seite fungiert. Ereignishandler sind Methoden, die Sie als Teil der Ihrem XAML zugeordneten partiellen Klasse schreiben. Diese Ereignishandler basieren auf den Delegaten, die von einem bestimmten Ereignis verwendet werden. Die Ereignishandlermethoden können öffentlich oder privat sein. Der private Zugriff funktioniert, weil der vom XAML erstellte Handler und die Instanz letztendlich durch die Codegenerierung verbunden werden. Im Allgemeinen wird empfohlen, die Ereignishandlermethoden in der Klasse öffentlich zu machen.

Hinweis  Ereignishandler für C++ werden nicht in partiellen Klassen definiert, sondern im Header als private Klassenmember deklariert.

Der sender-Parameter und Ereignisdaten

Der Handler, den Sie für das Ereignis schreiben, kann auf zwei Werte zugreifen. Diese Werte sind jedes Mal als Eingabe verfügbar, wenn der Handler aufgerufen wird. Der erste Wert ist sender. Dabei handelt es sich um einen Verweis auf das Objekt, dem der Handler angefügt ist. Der sender-Parameter ist als Object-Basistyp typisiert. Häufig wird sender in einen präziseren Typ umgewandelt. Diese Maßnahme ist nützlich, wenn Sie beabsichtigen, den Zustand direkt für das sender-Objekt zu überprüfen oder zu ändern. Abhängig davon, wo der Handler angefügt wird, und von anderen Designmerkmalen handelt es sich bei Ihrem eigenen App-Design entsprechend voraussichtlich um einen Typ, in den sender sicher umgewandelt werden kann.

Den zweiten Wert stellen Ereignisdaten dar. In der Regel sind diese in Signaturen als e-Parameter enthalten. Wenn Sie feststellen möchten, welche Eigenschaften für Ereignisdaten verfügbar sind, prüfen Sie den e-Parameter des Delegaten, der dem behandelten Ereignis zugewiesen ist. Verwenden Sie dann IntelliSense oder den Objektkatalog in Visual Studio. Sie können auch in der Referenzdokumentation von Windows Runtime nachschlagen.

Bei einigen Ereignissen ist die Kenntnis der speziellen Eigenschaftswerte der Ereignisdaten so wichtig wie die Kenntnis, dass das Ereignis ausgelöst wurde. Das gilt speziell bei Eingabeereignissen. Bei Zeigerereignissen kann die Position des Zeigers beim Auslösen des Ereignisses wichtig sein. Bei Tastaturereignissen wird durch alle möglichen Tastendrücke ein KeyDown- und KeyUp-Ereignis ausgelöst. Um zu bestimmen, welche Taste von einem Benutzer gedrückt wurde, müssen Sie auf die KeyRoutedEventArgs-Klasse zugreifen, die für den Ereignishandler verfügbar ist. Weitere Informationen zur Behandlung von Eingabeereignissen finden Sie unter Reaktion auf Tastatureingaben und Schnellstart: Zeiger. Bei Eingabeereignissen und Eingabeszenarien gibt es häufig weitere Überlegungen, die in diesem Thema nicht behandelt werden, wie das Erfassen des Zeigers bei Zeigerereignissen oder Zusatztasten und Plattformtastencodes für Tastaturereignisse.

Ereignishandler, die asynchrone Muster verwenden

In einigen Fällen wird die Verwendung von APIs empfohlen, die innerhalb eines Ereignishandlers ein asynchrones Muster verwenden. Beispielsweise können Sie eine Button in einer AppBar verwenden, um eine Dateiauswahl anzuzeigen. Viele der Dateiauswahl-APIs sind asynchron.

Wenn Ihr Ereignishandler Code mit dem asynchronen Muster (Schlüsselwort await in C#, Await in Visual Basic) verwendet, müssen Sie dem Ereignishandler das Schlüsselwort async (oder Async) hinzufügen. Andernfalls tritt ein Compiler-Fehler auf.

Ein Beispiel für Ereignishandler mit dem asynchronen Muster finden Sie unter Dateizugriff und -auswahl (in Erstellen Ihrer ersten Windows Store-App mit C# oder Visual Basic).

Hinzufügen von Ereignishandlern im Code

Es gibt noch andere Möglichkeiten als XAML, um einem Objekt einen Ereignishandler zuzuweisen. Sie können die spezielle Syntax zum Hinzufügen von Ereignishandlern einer Sprache nutzen, um bestimmten Objekten (auch Objekten, die in XAML nicht verwendet werden können) Ereignishandler im Code hinzufügen.

In C# wird für die Syntax der +=-Operator verwendet. Sie registrieren den Handler, indem Sie auf der rechten Seite des Operators auf den Namen der Ereignishandlermethode verweisen.

Wenn Objekten, die in der Laufzeit-UI erscheinen, Ereignishandler per Code hinzugefügt werden, ist es eine übliche Vorgehensweise, diese Handler als Reaktion auf ein Objektlebensdauer-Ereignis oder einen Rückruf hinzuzufügen, wie z. B. Loaded oder OnApplyTemplate. Die Ereignishandler für das relevante Objekt stehen dann zur Laufzeit für Ereignisse bereit, die von Benutzern eingeleitet werden. Dieses Beispiel veranschaulicht zunächst die XAML-Gliederung, sodass Sie sich die Struktur vorstellen können. Anschließend wird die C#-Sprachsyntax aufgeführt.


<Grid x:Name="LayoutRoot" Loaded="LayoutRoot_Loaded">
  <StackPanel>
    <TextBlock Name="textBlock1">Put the pointer over this text</TextBlock>
...
  </StackPanel>
</Grid>


void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += textBlock1_PointerEntered;
    textBlock1.PointerExited += textBlock1_PointerExited;
}

Eine ausführlichere Syntax ist vorhanden. 2005 wurde in C# der Rückschluss auf Delegaten als neues Feature eingeführt. Damit kann der Compiler die neue Delegatinstanz ableiten, und die vorherige, einfachere Syntax kann verwendet werden. Die Funktion der ausführlichen Syntax entspricht dem vorherigen Beispiel. Vor der Registrierung wird jedoch explizit eine neue Delegatinstanz erstellt. Der Delegatrückschluss wird somit nicht genutzt. Diese explizite Syntax ist zwar nicht so üblich, aber dennoch in einigen Codebeispielen anzutreffen.


void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += new PointerEventHandler(textBlock1_PointerEntered);
    textBlock1.PointerExited += new MouseEventHandler(textBlock1_PointerExited);
}

Für Visual Basic-Syntax gibt es zwei Möglichkeiten Sie können zum einen eine parallele C#-Syntax verwenden und Handler direkt den Instanzen anfügen. Dazu benötigen Sie das AddHandler -Schlüsselwort und den AddressOf-Operator, der den Handlermethodennamen dereferenziert.

Private Sub LayoutRoot_Loaded(ByVal sender As Object, ByVal e As PointerRoutedEventArgs e)
    AddHandler textBlock1.PointerEntered, AddressOf textBlock1_PointerEntered
    AddHandler textBlock1.PointerExited, AddressOf textBlock1_PointerExited
End Sub

Die zweite Möglichkeit für die Visual Basic-Syntax besteht darin, das Handles-Schlüsselwort für Ereignishandler zu verwenden. Das ist in Fällen angebracht, in denen Handler für Objekte voraussichtlich beim Laden vorhanden sind und für die Objektlebensdauer bestehen bleiben. Wenn Sie Handles für ein in XAML definiertes Objekt verwenden, müssen Sie einen Name/x:Name bereitstellen. Dieser Name wird zum Instanzenqualifizierer, der für den Instance.Event-Teil der Handles-Syntax benötigt wird. In diesem Fall benötigen Sie keinen Ereignishandler, der auf der Objektlebensdauer basiert, um das Anfügen der anderen Ereignishandler einzuleiten. Die Handles-Verbindungen werden beim Kompilieren der XAML-Seite erstellt.

Private Sub textBlock1_PointerEntered(ByVal sender As Object, ByVal e As PointerRoutedEventArgs) Handles textBlock1.PointerEntered
'...
End Sub

Hinweis  Visual Studio und die zugehörige XAML-Entwurfsoberfläche eignen sich im Allgemeinen besser für die Instanzbehandlung als für das Handles-Schlüsselwort. Denn das Erstellen der Ereignishandlerverknüpfung in XAML gehört zu einem typischen Designer-Entwickler-Workflow, und die Handles-Schlüsselworttechnik ist mit dem Verknüpfen der Ereignishandler in XAML nicht kompatibel.

Auch in C++ verwenden Sie die +=-Syntax. Es gibt jedoch Unterschiede zum allgemeinen C#-Format:

  • Es gibt keinen Rückschluss auf Delegaten. Sie müssen deshalb ref new für die Delegatinstanz verwenden.
  • Der Delegatenkonstruktor besitzt zwei Parameter und benötigt das Zielobjekt als ersten Parameter. Normalerweise geben Sie this an.
  • Der Delegatenkonstruktor benötigt die Methodenadresse als zweiten Parameter, sodass die &-Dereferenzierung vor dem Methodennamen steht.

textBlock1->PointerEntered += 
ref new PointerEventHandler(this,&BlankPage::textBlock1_PointerExited);

Entfernen von Ereignishandlern im Code

Das Entfernen von Ereignishandlern im Code ist in der Regel nicht erforderlich, auch wenn sie von Ihnen im Code hinzugefügt wurden. Das Verhalten der Objektlebensdauer für die meisten Windows-Runtime-Objekte, z. B. Seiten und Steuerelemente, zerstört die Objekte, wenn die Verbindung mit dem Haupt-Window und der dazugehörigen visuellen Struktur getrennt wird. Vorhandene Delegatverweise werden ebenfalls zerstört. In .NET erfolgt dies durch eine Garbage Collection, und in Windows-Runtime mit Visual C++-Komponentenerweiterungen (C++/CX) werden standardmäßig schwache Verweise verwendet.

In einigen seltenen Fällen sollten Ereignishandler explizit entfernt werden. Dazu zählen:

  • Für statische Ereignisse hinzugefügte Handler, für die keine konventionelle Garbage Collection durchgeführt werden kann. Die Ereignisse der Klassen CompositionTarget und Clipboard sind Beispiele für statische Ereignisse in der Windows-Runtime-API.
  • Testcode, in dem das Entfernen von Handlern sofort erfolgen soll, oder Code, in dem alte und neue Ereignishandler für ein Ereignis zur Laufzeit ausgetauscht werden sollen.
  • Die Implementierung eines benutzerdefinierten remove-Accessors.
  • Benutzerdefinierte statische Ereignisse.

Bei FrameworkElement.Unloaded oder Page.NavigatedFrom handelt es sich um mögliche Ereignisauslöser mit entsprechenden Positionen in der Zustandsverwaltung und der Objektlebensdauer, sodass sie zum Entfernen von Handlern für andere Ereignisse verwendet werden können.

Beispielsweise können Sie mit diesem Code einen Ereignishandler mit dem Namen textBlock1_PointerEntered aus dem Zielobjekt textBlock1 entfernen.


textBlock1.PointerEntered -= textBlock1_PointerEntered;

Sie können Handler auch in solchen Fällen entfernen, in denen das Ereignis über ein XAML-Attribut hinzugefügt wurde, was bedeutet, dass der Handler in generiertem Code hinzugefügt wurde. Dies ist einfacher, wenn Sie einen Name-Wert für das Element bereitstellen, dem der Handler angehängt wurde, weil dadurch später ein Objektverweis für den Code bereitgestellt wird. Sie können jedoch auch in der Objektstruktur nach dem erforderlichen Objekt suchen, wenn kein Name für das Objekt vorhanden ist.

Wenn Sie einen Ereignishandler in C++/CX entfernen müssen, benötigen Sie ein Registrierungstoken, das Sie im Rückgabewert der +=-Ereignishandlerregistrierung erhalten haben sollten. Der Grund ist, dass es sich bei dem Wert, den Sie für die rechte Seite der Aufhebung der -=-Registrierung in C++/CX-Syntax verwenden, um das Token handelt, nicht beim Methodennamen. Für C++ können Sie als XAML-Attribut hinzugefügte Handler nicht entfernen, da der generierte C++-Code kein Token speichert.

Routingereignisse

Die Windows-Runtime mit C#, Visual Basic oder C++ unterstützt das Konzept von Routingereignissen für bestimmte Ereignisse, die es für die meisten UI-Elemente gibt. Diese Ereignisse unterstützen Eingaben und Benutzerinteraktionen und werden für die UIElement-Basisklasse implementiert. Die folgenden Eingabeereignisse sind Routingereignisse:

Ein Routingereignis kann potenziell von einem untergeordneten Objekt an jedes seiner jeweils übergeordneten Objekte in der Objektstruktur weitergeleitet werden. Die XAML-Struktur Ihrer UI kommt dieser Struktur nahe, wobei der Stamm dieser Struktur dem Stammelement in XAML entspricht. Die tatsächliche Objektstruktur kann leicht vom XAML abweichen, da die Objektstruktur keine XAML-Sprachfeatures wie Eigenschaftenelementtags enthält. Routingereignisse durchlaufen die Struktur im Allgemeinen nach dem Bubblingkonzept von untergeordneten XAML-Objektelementen zu den sie enthaltenden übergeordneten Objekten. Das Ereignis und die zugehörigen Ereignisdaten können an mehreren Objekten entlang der Ereignisroute behandelt werden, und die Route wird möglicherweise bis zum Erreichen des Stammelements verfolgt.

Wenn Sie Webtechnologien wie Dynamic HTML (DHTML) oder HTML5 kennen, sind Sie möglicherweise bereits mit dem Bubbling-Konzept vertraut.

Wenn für ein Routingereignis ein Bubbling durch die zugehörige Ereignisroute erfolgt, greifen alle angefügten Ereignishandler auf eine freigegebene Instanz von Ereignisdaten zu. Deshalb werden Änderungen an Ereignisdaten an den nächsten Handler weitergegeben, wenn einer der Handler Schreibzugriff auf Ereignisdaten besitzt. Die Daten entsprechen dann möglicherweise nicht mehr den ursprünglichen Ereignisdaten. Wenn ein Ereignis ein Routingereignisverhalten besitzt, wird in der Referenzdokumentation entsprechend darauf hingewiesen.

OriginalSource-Eigenschaft von "RoutedEventArgs"

Wenn ein Ereignis entlang einer Route ein Bubbling durchläuft, ist sender nicht mehr das Objekt, das das Ereignis ausgelöst hat. Stattdessen ist sender das Objekt, an das der aufgerufene Handler angefügt ist.

In einigen Fällen interessieren Sie sich nicht für das sender-Objekt, sondern eher dafür, auf welchen untergeordneten Objekten sich möglicherweise der Mauszeiger befindet oder auf welchem Objekt der Fokus beim Drücken einer Taste durch den Benutzer lag. Für diese Fälle wird der Wert der OriginalSource-Eigenschaft verwendet. An allen Punkten in der Route meldet OriginalSource das ursprüngliche Objekt, von dem das Ereignis ausgelöst wurde, und nicht, wo der Handler angefügt ist. Bei UIElement-Eingabeereignissen ist das ursprüngliche Objekt jedoch häufig ein Objekt, das nicht sofort vom XAML auf Seitenebene erkannt wird. Es kann sich stattdessen um einen Vorlagenteil eines Steuerelements handeln. Wenn der Benutzer z. B. den Mauszeiger über die äußere Kante eines Button-Objekts zieht, ist OriginalSource bei den meisten Zeigerereignissen ein Vorlagenteil in der Template und nicht das Button-Objekt selbst. Bei Standardvorlagen ist dieser Teil ein Border in der zugrunde liegenden XAML-Vorlage, und dieser Border wird als Wert von OriginalSource übergeben.

Tipp  Das Eingabe-Eventbubbling ist besonders dann hilfreich, wenn Sie ein Vorlagensteuerelement erstellen. Auf jedes Steuerelement, das eine Vorlage besitzt, kann durch seinen Consumer eine neue Vorlage angewendet werden. Wenn der Consumer die neue Vorlage deklariert, könnte er unbeabsichtigt eine Ereignisbehandlung löschen, die im Standardvorlagen-XAML deklariert ist. Sie können trotzdem eine Ereignisbehandlung auf Steuerelementebene bereitstellen. Fügen Sie dazu Handler als Teil der OnApplyTemplate-Überschreibung in der Klassendefinition an, und fangen Sie die Eingabeereignisse ab, die bei der Insanziierung per Bubbling zum Stamm des Steuerelements weitergeleitet werden. Dort kann die Ereignisbehandlung nicht vom Vorlagenverhalten außer Kraft gesetzt werden kann.

Handled-Eigenschaft

Einige Ereignisdatenklassen für bestimmte Routingereignisse enthalten eine Eigenschaft mit dem Namen Handled. Beispiele finden Sie unter PointerRoutedEventArgs.Handled, KeyRoutedEventArgs.Handled und DragEventArgs.Handled. Handled ist eine festlegbare boolesche Eigenschaft.

Wenn die Handled-Eigenschaft auf true festgelegt wird, wirkt sich das auf das Ereignissystemverhalten aus. Ist Handled auf true festgelegt, wird das Routing für die meisten Ereignishandler beendet. Das Ereignis wird nicht über die Route weitergeleitet, um andere angefügte Handler über dieses spezielle Ereignis zu informieren. Was als "Aktion behandelt" im Kontext des Ereignisses bedeutet und wie Ihre Anwendung auf ein behandeltes Ereignis reagiert, liegt in Ihrem Ermessen. Berücksichtigen Sie aber, wie das Ereignissystem reagiert, wenn Sie den Wert für eine Handled-Eigenschaft in Ihren Ereignishandlern festlegen.

Nicht bei allen Routingereignissen kann eine Route auf diese Weise abgebrochen werden. Beispielsweise werden GotFocus und LostFocus immer die gesamte Route bis zum Stamm weitergeleitet, und ihre Ereignisdatenklassen besitzen keine Handled-Eigenschaft, die dieses Verhalten beeinflussen kann.

Eingabeereignishandler in Steuerelementen

Bei bestimmten Windows Runtime-Steuerelementen wird das Handled-Konzept manchmal intern für Eingabeereignisse verwendet. Dadurch kann der Anschein erweckt werden, dass niemals ein Eingabeereignis eintritt, weil es von Ihrem Benutzercode nicht verarbeitet werden kann Die Button-Klasse enthält z. B. Logik, mit der gezielt das allgemeine Eingabeereignis PointerPressed behandelt wird. Grund hierfür ist, dass Schaltflächen ein Click-Ereignis auslösen, das durch Eingaben mit gedrücktem Zeiger sowie durch andere Eingabemodi initiiert wird (wie der Behandlung bestimmter Tasten, sobald diese den Fokus erhalten). Für Klassendesignzwecke wird das Rohdateneingabe-Ereignis konzeptionell behandelt. Klassenconsumer wie Ihr Benutzercode können stattdessen wählen, ob sie dasClick-Ereignis, das eher einem Steuerelement entspricht, behandeln oder nicht. In den entsprechenden Themen zu den speziellen Steuerelementklassen in der API-Referenz für die Windows-Runtime wird häufig das von der Klasse implementierte Ereignisbehandlungsverhalten erwähnt. In einigen Fällen können Sie das Verhalten ändern, indem Sie OnEvent-Methoden überschreiben. Sie können z. B. ändern, wie Ihre von TextBox abgeleitete Klasse auf Tasteneingaben reagiert, indem Sie Control.OnKeyDown überschreiben.

Registrieren von Handlern für bereits behandelte Routingereignisse

Weiter oben wurde erwähnt, dass die meisten Handler nicht aufgerufen werden, wenn Handled auf true festgelegt ist. Die AddHandler-Methode bietet jedoch eine Technik, um einen Handler anzufügen, der für die Route immer aufgerufen wird. Das geschieht selbst dann, wenn für andere Handler an früherer Stelle in der Route Handled in den geteilten Ereignisdaten auf true festgelegt wurde. Diese Technik ist nützlich, wenn ein von Ihnen verwendetes Steuerelement das Ereignis in seiner inneren Zusammensetzung behandelt hat. Sie eignet sich auch für spezielle Steuerelementlogik, bei der Sie jedoch noch immer auf eine Steuerelementinstanz oder auf eine Stelle weiter oben in der Route reagieren möchten. Sie sollte jedoch mit Bedacht eingesetzt werden, da sie dem Zweck von Handled widersprechen und dem beabsichtigten Einsatz des Steuerelements oder dem Objektmodell zuwiderlaufen kann.

Nur Routingereignisse mit entsprechenden Routingereignisbezeichnern können die Technik zur AddHandler-Ereignisbehandlung nutzten. Denn der Bezeichner wird als Eingabe für die AddHandler-Methode benötigt. In der Referenzdokumentation zu AddHandler finden Sie eine Liste der Ereignisse, für die Routingereignisbezeichner verfügbar sind. Diese Liste stimmt größtenteils mit der bereits gezeigten Liste mit Routingereignissen überein. Die letzten beiden Ereignisse in der Liste, GotFocus und LostFocus, stellen eine Ausnahme dar, da sie keinen Routingereignisbezeichner besitzen. Daher können Sie AddHandler nicht für diese Ereignisse verwenden.

Routingereignisse außerhalb der visuellen Struktur

Bestimmte Objekte sind Bestandteil einer Beziehung mit der primären visuellen Struktur. Diese ist konzeptionell wie z. B. eine Überlagerung über die visuellen Hauptobjekte. Diese bestimmten Objekte gehören nicht zu den üblichen Beziehungen zwischen übergeordneten und untergeordneten Elementen, mit denen alle Strukturelemente mit dem visuellen Stamm verbunden sind. Das betrifft jedes angezeigte Popup- oder ToolTip-Element. Wenn Sie Routingereignisse eines Popup- oder ToolTip-Elements behandeln möchten, platzieren Sie die Handler für bestimmte UI-Elemente innerhalb des Popup- oder ToolTip-Elements und nicht direkt für das Popup- oder ToolTip-Element. Verlassen Sie sich nicht auf das Routing innerhalb einer Zusammensetzung, die für Popup- oder ToolTip-Inhalt ausgeführt wird. Denn das Ereignisrouting funktioniert nur entlang der visuellen Hauptstruktur. Ein Popup- oder ToolTip-Element wird nicht als übergeordnetes Element von untergeordneten UI-Elementen angesehen und empfängt das Routingereignis in keinem Fall, selbst wenn es versucht, Elemente wie den Popup-Standardhintergrund als Erfassungsbereich für Eingabeereignisse zu verwenden.

Entfernen von Ereignishandlern

Unter bestimmten Umständen kann es wünschenswert sein, Ereignishandler während der Anwendungslebensdauer zu entfernen. Zum Entfernen von Ereignishandlern verwenden Sie die sprachspezifische Syntax. In C# verwenden Sie den -=-Operator. In Visual Basic verwenden Sie die RemoveHandler-Funktion. In beiden Fällen verweisen Sie auf den Namen der Ereignishandlermethode.

Treffertests und Eingabeereignissse

Bei einem Treffertest wird ermittelt, ob ein Element für eine Maus-, Finger- oder Stifteingabe sichtbar ist. Bei Fingereingabeaktionen und interaktionsspezifischen Ereignissen oder Manipulationsereignissen, die aus einer Fingereingabeaktion resultieren, muss ein Element bei Treffertests sichtbar sein, damit es der Ereignisquelle entsprechen und das der Aktion zugeordnete Ereignis auslösen kann. Andernfalls durchläuft die Aktion das Element bis zu zugrunde liegenden oder übergeordneten Elementen in der visuellen Struktur. Treffertests werden von mehreren Faktoren beeinflusst. Sie können jedoch feststellen, ob ein bestimmtes Element Eingabeereignisse auslösen kann, indem Sie die zugehörige IsHitTestVisible-Eigenschaft überprüfen. Diese Eigenschaft gibt true nur dann zurück, wenn das Element die folgenden Kriterien erfüllt:

  • Der Visibility-Eigenschaftenwert des Elements ist Visible.
  • Der Background- oder Fill-Eigenschaftswert des Elements ist nicht null. Ein null-Wert für Brush führt zur Transparenz und Unsichtbarkeit von Treffertests. (Wenn Sie ein Element transparent machen und zugleich Treffertests für das Element ermöglichen möchten, verwenden Sie einen Transparent-Pinsel anstelle von null.)

    Hinweis  Background und Fill werden nicht durch UIElement, sondern durch unterschiedliche abgeleitete Klassen wie Control und Shape definiert. Die von Ihnen für Vorder- und Hintergrundeigenschaften verwendeten Implikationen von Pinseln sind jedoch für Treffertests und Eingabeereignisse identisch. Dabei ist es unerheblich, welche Unterklasse die Eigenschaften implementiert.

  • Wenn das Element ein Steuerelement ist, muss der zugehörige IsEnabled-Eigenschaftenwert auf true festgelegt sein.
  • Das Element muss über reale Dimensionen verfügen. Ein Element, bei dem ActualHeight und ActualWidth 0 sind, kann keine Eingabeereignisse auslösen.

Bei einigen Steuerelementen sind besondere Regeln bezüglich Treffertests zu beachten. TextBlock hat beispielsweise keine Background-Eigenschaft. Dennoch können innerhalb des gesamten Bereichs der zugehörigen Dimensionen Treffertests ausgeführt werden. Für Image- und MediaElement-Steuerelemente können in den zugehörigen definierten Rechtecksdimensionen Treffertests ausgeführt werden. Dabei ist es unerheblich, ob in der Medienquelldatei transparente Inhalte wie Alphakanäle angezeigt werden.

Für die meisten Panel-Klassen und Border-Elemente können im eigenen Hintergrund zwar keine Treffertests ausgeführt werden, sie können aber trotzdem Benutzereingabeereignisse verarbeiten, die von den in ihnen integrierten Elementen weitergeleitet werden.

Elemente, die sich an der gleichen Position wie das Ereignis einer Benutzereingabe befinden, können unabhängig davon ermittelt werden, ob sie für Treffertests infrage kommen. Rufen Sie dazu die FindElementsInHostCoordinates-Methode auf. Diese Methode findet die Elemente, wie der Name nahe legt, an einer Position relativ zu einem angegebenen Hostelement. Sie sollten jedoch nicht vergessen, dass sich Transformationen und Layoutänderungen auf das Koordinatensystem eines Elements auswirken und somit die an einer bestimmten Position gefundenen Elemente beeinflussen.

Steuerung

Eine geringe Anzahl von UI-Elementen unterstützt die Steuerung. Die Steuerung verwendet eingabebezogene Routingereignisse in der zugrunde liegenden Implementierung und ermöglicht die Verarbeitung verwandter UI-Eingaben (eine bestimmte Zeigeraktion oder Zugriffstaste) durch das Aufrufen eines einzelnen Befehlshandlers. Wenn die Steuerung für ein UI-Element verfügbar ist, sollten Sie dessen Steuerungs-APIs verwenden anstelle einzelner Eingabeereignisse. Weitere Informationen finden Sie unter ButtonBase.Command.

Benutzerdefinierte Ereignisse in der Windows-Runtime

Beim Definieren von benutzerdefinierten Ereignissen hängt die Vorgehensweise beim Hinzufügen des Ereignisses und die Bedeutung für Ihren Klassenentwurf erheblich von der verwendeten Programmiersprache ab.

  • Für C# und Visual Basic definieren Sie ein CLR-Ereignis. Sie können das .NET-Standardereignismuster verwenden, es sei denn, Sie verwenden benutzerdefinierte Accessoren (add/remove). Zusätzliche Tipps:
  • Für C++/CX lesen Sie Ereignisse (C++/CX).
    • Verwenden Sie auch für Ihre eigenen Verwendungen von benutzerdefinierten Ereignissen benannte Verweise. Verwenden Sie nicht Lambda, da dadurch u. U. ein Zirkelverweis erstellt wird.

Sie können ein benutzerdefiniertes Routingereignis nicht deklarieren; Routingereignisse sind auf den Satz aus der Windows-Runtime beschränkt.

Das Definieren eines benutzerdefinierten Ereignisses erfolgt in der Regel im Rahmen der Definition eines benutzerdefinierten Steuerelements. Eine Abhängigkeitseigenschaft mit einem Rückruf für Eigenschaftsänderungen ist ein gängiges Muster, genau wie das Definieren eines benutzerdefinierten Ereignisses, das in manchen oder in allen Fällen durch den Abhängigkeitseigenschaftsrückruf ausgelöst wird. Benutzer Ihres Steuerelements haben keinen Zugriff auf den von Ihnen definierten Rückruf für Eigenschaftsänderungen; die beste Methode ist das Bereitstellen eines Benachrichtigungsereignisses. Weitere Informationen finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.

Verwandte Themen

Übersicht über XAML
Schnellstart: Fingereingabe
Reaktion auf Tastatureingaben
.NET-Ereignisse und -Delegate
Erstellen von Windows-Runtime-Komponenten
AddHandler

 

 

© 2013 Microsoft. Alle Rechte vorbehalten.