Silverlight Doppelt klicken einfach laden
Kommentare

Wie implementiert man eigentlich in Silverlight einen Doppelklick? Und wie schreibt man einen eigenen Preloader? Gregor Biswanger erklärt das in nachfolgendem Artikel.

Doppelklick implementieren

Da sich der Doppelklick nicht als ein Webstandard etabliert hat, unterstützt Silverlight auch nur den einfachen Mausklick. Dennoch gibt es den Doppelklick bei einer RIA-Anwendung des öfteren. Als Lösung wird ein Timer erzeugt, der bei einem einfachen Klick nur kurze Zeit aktiv ist. Sollte beim wiederholten Klicken festgestellt werden, dass der Timer aktiv ist, wird dies als Doppelklick behandelt. Andernfalls läuft der Timer nach einer kurzen Zeit ab und deaktiviert sich selbst. Als Beispiel wird ein neuer Button mit einem Klick-Event angelegt und anschließend die Timer-Logik implementiert (Listing 1 und Abb. 1).

namespace SilverlightApplication
{
    public partial class MainPage : UserControl
    {
        private DispatcherTimer _doubleClickTimer;

        public MainPage()
        {
            InitializeComponent();

            _doubleClickTimer = new DispatcherTimer();
            _doubleClickTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
            _doubleClickTimer.Tick += DoubleClickTimerTick;
        }

        private void DoubleClickTimerTick(object sender, EventArgs e)
        {
            _doubleClickTimer.Stop();
        }

        private void BnTest_Click(object sender, RoutedEventArgs e)
        {
            if(_doubleClickTimer.IsEnabled)
            {
                MessageBox.Show("Doppelklick ausgeführt!");
            }
            else
            {
                _doubleClickTimer.Start();
            }
        }
    }
}  
Button mit einem Doppelklick implementiert
Button mit einem Doppelklick implementiert
Der eigene Assembly Preloader

Beim Laden einer Silverlight-Anwendung wird der blaue ladende Ring (Preloader) als Standard angezeigt. Um auch beim längeren Laden weiterhin die Corporate Identity beizubehalten, ist ab Silverlight 1 das Schreiben eines eigenen Preloaders möglich. Dafür musste man bisher eine XAML-Datei auf den Server mittels JavaScript koordinieren. Dieser unangenehme Weg kann aber auch mit einem eigenen Assembly Preloader viel eleganter gelöst werden. Dazu wird eine 4 KB kleine Silverlight-Assembly als Preloader der hauptsächlichen Silverlight-Anwendungs-Assembly in den Speicher geladen und anschließend instanziiert und ausgeführt.

Im vorliegenden Beispiel des Artikels wird ein neues Silverlight-Projekt mit dem Namen „SilverlightCustomPreloader“ angelegt. Der Preloader soll einen Fortschrittsbalken und einen Text mit der geladenen Prozentinformation darstellen. Der XAML-Code für die MainPage.XAML ist in Listing 2 zu finden.


..
        
            Loading
            
            
        
..
  

Anschließend wird dem Projekt eine neue Silverlight-Anwendung hinzugefügt. Diese fungiert als hauptsächliche Anwendung, die vom Preloader geladen wird. Die XAP-Datei wird vom Preloader in der Code-Behind-Datei mittels WebClient geladen. Wenn dieser Vorgang abgeschlossen ist, wird eine Instanz erzeugt und ausgeführt (Listing 3).

namespace SilverlightCustomPreloader
{
    public partial class MainPage : UserControl
    {
        private string _assemblyXAP = "SilverlightApplication.xap";
        private string _assemblyFile = "SilverlightApplication.dll";
        private string _assemblyInstanceName = "SilverlightApplication.MainPage";

        public MainPage()
        {
            InitializeComponent();

            WebClient client = new WebClient();
            client.OpenReadCompleted += ClientOpenReadCompleted;
            client.DownloadProgressChanged += ClientDownloadProgressChanged;
            client.OpenReadAsync(new Uri(_assemblyXAP, UriKind.RelativeOrAbsolute));
        }

        private void ClientOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            StreamResourceInfo streamResourceXAP = new StreamResourceInfo(e.Result as Stream, null);
            StreamResourceInfo streamResourceDLL = Application.GetResourceStream(streamResourceXAP, new Uri(_assemblyFile, UriKind.Relative));
            
            AssemblyPart assemblyPart = new AssemblyPart();
            Assembly assembly = assemblyPart.Load(streamResourceDLL.Stream);

            UserControl userControl = (UserControl) assembly.CreateInstance(_assemblyInstanceName);
            LayoutRoot.Children.Clear();
            LayoutRoot.Children.Add(userControl);
        }

        private void ClientDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            Progress.Value = e.ProgressPercentage;
            Downloaded.Text = (e.BytesReceived/1024) + "kb /" + e.TotalBytesToReceive;
        }
    }
}  

Ganz wichtig zu beachten ist, dass der Sourcecode aus Listing 3 ohne jegliche Fehlerbehandlung veranschaulicht wird. Diese müsste auf jeden Fall noch zusätzlich implementiert werden. Als kleiner Tipp: Wenn der Preloader die Anwendung zu schnell geladen hat, kann in der Hauptanwendung die Zuweisung von LayoutRoot in der App_StartUp-Methode der App.cs-Datei auskommentiert werden, dann wird die Anwendung nicht geladen und der Preloader bleibt im Vordergrund. Bei enorm langen Ladezeiten empfiehlt sich ein Einführungsvideo zu starten, während die eigentliche Anwendung startet.

Gregor Biswanger ist Solution Architect und Silverlight-Fachexperte bei der Firma impuls Informationsmanagement GmbH in Nürnberg. Seine Schwerpunkte liegen im Bereich der .NET-Architektur und agilen Prozessen. Biswanger ist auch freier Autor, Trainer, Projektbegleiter, Speaker und Microsoft CLIPler der INdotNET (Ingolstädter .NET Developers Group). Sie erreichen seinen Blog unter www.dotnet-blog.net.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -