In diesem Artikel beschreibe ich eine Lösung, die es ermöglicht, eine Aktion erst dann zu starten, wenn die Anwendung vollständig im Browserfenster sichtbar ist. Diese Technik kann beispielsweise für das Erstellen einer Silverlight-Anwendung nützlich sein, mit der eine Werbung dargestellt werden soll.
Generelle Vorgehensweise
Die vorgestellte Lösung verwendet einen Trick. Dieser Trick besteht darin, dass oberhalb und unterhalb der eigentlichen Anwendung jeweils eine weitere Anwendung eingebettet wird. Es gibt also die Hauptanwendung, die den eigentlichen Inhalt darstellen soll. Unmittelbar oberhalb dieser Anwendung ist in der html-Seite eine weitere Anwendung eingebettet. Das ist die TopApp. Unmittelbar unterhalb der Hauptanwendung ist noch eine Anwendung in die html-Seite eingebettet. Das ist die BottomApp. Die beiden Anwendungen TopApp und BottomApp haben jeweils eine Breite, die der Breite der Hauptanwendung entspricht. Die Höhe von TopApp und BottomApp beträgt 1px.
Die drei Anwendungen kommunizieren über LocalMessaging miteinander. Wenn der Nutzer die html-Seite von oben nach unten scrollt, wird zunächst die TopApp sichtbar. Dann wird die Hauptanwendung sichtbar. Und zuletzt wird die BottomApp sichtbar. Sobald die TopApp sichtbar wird, beginnt das Ereignis "CompositionTarget.Rendering()" der TopApp zu feuern. Diesem Ereignis ist ein Delegat hinzugefügt. Die Methode, auf die dieser Delegat zeigt, hat die Aufgabe, an die Hauptanwendung eine Nachricht zu senden. Die Hauptanwendung notiert das in der Variablen "IsTopVisible" und setzt deren Wert auf "True". Damit die Methode, die im Sender für das Senden der Nachricht verantwortlich ist, entfernt wird, antwortet die Hauptanwendung dem Sender der TopApp mit einem TrueString. Damit der Sender von TopApp diese Antwort verarbeiten kann, ist dem Ereignis "SendCompleted()" des "LocalMessageSender" ein Delegat hinzugefügt. Die Methode, auf die dieser Delegat zeigt, hat die Aufgabe, die Anwort der Hauptanwendung zu verarbeiten. Das heisst, sie entfernt den Delegaten, der dem "CompositionTarget.Rendering()" von TopApp hinzugefügt worden war. Ebenso wie die TopApp, schickt auch die BottomApp an die Hauptanwendung eine Nachricht, sobald die BottomApp sichtbar ist. Die Hauptanwendung notiert das wiederum in einer Variablen. Das ist die Variable "IsBottomVisible", deren Wert auf "True" gesetzt wird. Wenn sowohl "IsTopVisible" als auch "IsBottomVisible" den Wert "True" haben, ist die Hauptanwendung vollständig sichtbar. Die Hauptanwendung kann dann die Aktion starten, die erfolgen soll, sobald sie vollständig sichtbar ist. Damit die Hauptanwendung reagieren kann, wird dem Ereignis "CompositionTarget.Rendering()" der Hauptanwendung ein Delegat hinzugefügt. Die Methode, auf die dieser Delegat zeigt, überprüft die beiden Variablen "IsTopVisible" und "IsBottomVisible" auf den Wert "True", führt dann die Aktion durch und entfernt schließlich den Delegaten wieder.
Quellcode
Nachfolgend ist der Quellcode der drei Anwendungen abgebildet.
1. "TopApp"
Imports System.Windows.Messaging
' ##############
' TOP SENDER App
' ##############
Partial Public Class MainPage
Inherits UserControl
Public Sub New()
InitializeComponent()
AddHandler CompositionTarget.Rendering, AddressOf SendMessages
AddHandler TopSender.SendCompleted, AddressOf ListenToResponse
End Sub
Private TopSender As New LocalMessageSender("SilverLawTopReceiver")
Private Sub SendMessages(ByVal sender As Object, ByVal e As EventArgs)
TopSender.SendAsync(Boolean.TrueString)
End Sub
Private Sub ListenToResponse(ByVal sender As Object, ByVal e As SendCompletedEventArgs)
If e.Response = Boolean.TrueString Then
RemoveHandler CompositionTarget.Rendering, AddressOf SendMessages
RemoveHandler TopSender.SendCompleted, AddressOf ListenToResponse
MessageBox.Show("TopSender received True-Message as a response.")
End If
End Sub
End Class
2. "MainApp"
Imports System.Windows.Messaging
' ####################
' MAIN SILVERLIGHT APP
' ####################
Partial Public Class MainPage
Inherits UserControl
Public Sub New()
InitializeComponent()
AddHandler CompositionTarget.Rendering, AddressOf ListenToVisibility
AddHandler MainTopReceiver.MessageReceived, AddressOf TopMessageReceived
MainTopReceiver.Listen()
AddHandler MainBottomReceiver.MessageReceived, AddressOf BottomMessageReceived
MainBottomReceiver.Listen()
End Sub
#Region " TOP VISIBILITY MESSAGING "
Private IsTopVisible As Boolean
Private MainTopReceiver As New LocalMessageReceiver("SilverLawTopReceiver")
Private Sub TopMessageReceived(ByVal sender As Object, ByVal e As MessageReceivedEventArgs)
If e.Message = Boolean.TrueString Then
Me.IsTopVisible = True
tbTopInfo.Text = "Top side visible."
e.Response = Boolean.TrueString
End If
End Sub
#End Region
#Region " BOTTOM VISIBILITY MESSAGING "
Private IsBottomVisible As Boolean
Private MainBottomReceiver As New LocalMessageReceiver("SilverLawBottomReceiver")
Private Sub BottomMessageReceived(ByVal sender As Object, ByVal e As MessageReceivedEventArgs)
If e.Message = Boolean.TrueString Then
Me.IsBottomVisible = True
tbBottomInfo.Text = "Bottom side visible."
e.Response = Boolean.TrueString
End If
End Sub
#End Region
#Region " LISTENING FOR FULL VISIBILITY OF THE APP "
Private Sub ListenToVisibility(ByVal sender As Object, ByVal e As EventArgs)
If Me.IsTopVisible = True And Me.IsBottomVisible = True Then
LayoutRoot.Background = New SolidColorBrush(Colors.DarkGray)
RemoveHandler CompositionTarget.Rendering, AddressOf ListenToVisibility
End If
End Sub
#End Region
End Class
3. "BottomApp"
Imports System.Windows.Messaging
' #################
' BOTTOM SENDER APP
' #################
Partial Public Class MainPage
Inherits UserControl
Public Sub New()
InitializeComponent()
AddHandler CompositionTarget.Rendering, AddressOf SendMessages
AddHandler BottomSender.SendCompleted, AddressOf ListenToResponse
End Sub
Private BottomSender As New LocalMessageSender("SilverLawBottomReceiver")
Private Sub SendMessages(ByVal sender As Object, ByVal e As EventArgs)
BottomSender.SendAsync(Boolean.TrueString)
End Sub
Private Sub ListenToResponse(ByVal sender As Object, ByVal e As SendCompletedEventArgs)
If e.Response = Boolean.TrueString Then
RemoveHandler CompositionTarget.Rendering, AddressOf SendMessages
RemoveHandler BottomSender.SendCompleted, AddressOf ListenToResponse
MessageBox.Show("BottomSender received True-Message as a response.")
End If
End Sub
End Class
Beispielanwendung
Eine Beispielanwendung, mit der diese Technik demonstriert wird, findet man unter diesem Link. Sobald die Hauptanwendung vollständig sichtbar ist, wechselt die Hintergrundfarbe der Anwendung von Schwarz zu Dunkelgrau.
Viel Spass damit.
Keine Kommentare:
Kommentar veröffentlichen