Daily Demo: Silverlight Install out of browser & Check for Update Behaviors

A great feature in Silverlight 3 is the capability to install applications out-of-browser. For those applications it is very useful to check, whether there is an update at the original location, where they are coming from.

My simple application checks this using behaviors, which can be reused for any applications. Just one feature is very important to enable –> The Out-Of-Browser Feature in your application.

The install-Behavior checks the Install-State of the application, and hide the control which contains the Install-Feature, if it is already installed.

Live Preview

image

The in-browser version, with an Install button.

image

The same application after installing it local.

image

The out-of-browser-application without the install button (because, it is already installed Wink)

image

The Update Dialog, when an update is available. You will not see this feature in the preview, because I will not update it regularly.

No code needed in your application

XAML-Code

 <UserControl
    x:Class="SmallTextEditor.MainPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:TheOliver="clr-namespace:TheOliver.Controls">
    
    <Grid
        x:Name="LayoutRoot"
        Background="White">

        <i:Interaction.Triggers>
            <i:EventTrigger
                EventName="Loaded">
                <TheOliver:CheckForUpdateBehavior />
            </i:EventTrigger>

        </i:Interaction.Triggers>

        <Grid.RowDefinitions>
            <RowDefinition
                Height="28*" />
            <RowDefinition
                Height="272*" />
        </Grid.RowDefinitions>
        <RichTextBox
            x:Name="_textbox"
            Grid.Row="1"
            IsEnabled="False" />
        <StackPanel
            HorizontalAlignment="Left"
            Name="stackPanel1"
            Orientation="Horizontal">
            <Button
                Content="New"
                Height="23"
                Name="_new"
                IsEnabled="False" />
            <Button
                Content="Open"
                Height="23"
                Name="_open"
                IsEnabled="False" />
            <Button
                Content="Save"
                Height="23"
                Name="_save"
                IsEnabled="False" />

            <Button
                Content="Install Local"
                Height="23"
                Name="_install">
                <i:Interaction.Triggers>
                    <i:EventTrigger
                        EventName="Click">
                        <TheOliver:InstallOutOfBrowserBehavior />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </StackPanel>
    </Grid>
</UserControl>

Sourcecode for Install-Out-Of-Browser-Behavior

 

 // Copyright © Microsoft Corporation.  All Rights Reserved.
// This code released under the terms of the 
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)

using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Controls;

namespace TheOliver.Controls
{
    public class InstallOutOfBrowserBehavior  : TargetedTriggerAction<FrameworkElement>
    {
        UIElement _element;

        protected override void OnAttached()
        {
            _element = this.Target as UIElement;

            if (!Application.Current.IsRunningOutOfBrowser)
            {
                 Application.Current.InstallStateChanged += (s, e) =>
                    {
                        CheckInstallState();
                    };

                CheckInstallState();

                if (_element is Button)
                {
                    (_element as Button).Click += (s, e) =>
                        {
                            InstallOOB();
                        };
                }
                else
                {
                    _element.MouseLeftButtonDown += (s, e) =>
                    {
                        InstallOOB();
                    };
                }
            }
            else
            {
                _element.Visibility = Visibility.Collapsed;
            }
            base.OnAttached();
        }

        private void InstallOOB()
        {
            if (Application.Current.InstallState != InstallState.Installed &&
                Application.Current.InstallState != InstallState.Installing)
            {
                Application.Current.Install();
            }
        }

        private void CheckInstallState()
        {
            if (Application.Current.InstallState == InstallState.Installed ||
                Application.Current.InstallState == InstallState.Installing)
            {
                _element.Visibility = Visibility.Collapsed;
            }
            else
            {
                _element.Visibility = Visibility.Visible;
            }
        }

        protected override void Invoke(object o)
        {
            
        }
    }
}

Sourcecode for CheckForUpdateBehavior

 // Copyright © Microsoft Corporation.  All Rights Reserved.
// This code released under the terms of the 
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)

using System.Windows;
using System.Windows.Interactivity;

namespace TheOliver.Controls
{
    public class CheckForUpdateBehavior  : TargetedTriggerAction<FrameworkElement>
    {
        UIElement _element;

        protected override void OnAttached()
        {
            // Works only out-of-browser
            if (Application.Current.IsRunningOutOfBrowser)
            {
                _element = this.AssociatedObject as UIElement;
            }
            base.OnAttached();
        }

        protected override void Invoke(object o)
        {
            if (_element != null)
            {
                Application.Current.CheckAndDownloadUpdateCompleted += (s, e) =>
                {
                    if (e.UpdateAvailable)
                    {
                        MessageBox.Show(UpdateIsAvailableMessageText);
                    }
                };
                Application.Current.CheckAndDownloadUpdateAsync();
            }
        }

        public string UpdateIsAvailableMessageText
        {
            get { return (string)GetValue(UpdateIsAvailableMessageTextProperty); }
            set { SetValue(UpdateIsAvailableMessageTextProperty, value); }
        }

        public static readonly DependencyProperty UpdateIsAvailableMessageTextProperty =
            DependencyProperty.Register(
                "UpdateIsAvailableMessageText", 
                typeof(string), 
                typeof(CheckForUpdateBehavior), 
                new PropertyMetadata("Update is available. Please restart your application"));

        
    }
}

Solutiondownload

 

Best regards,

The-Oliver