Archive

Archive for janvier 2010

[SL4] : Toast notifications

Une nouveauté de Silverlight 4 est la possibilité de réaliser des notifications sur le bureau de l’utilisateur à l’instar des notifications Outlook.  

Toutefois cette fonctionnalité n’est proposée que si votre application est en mode OOB ! dommage !  

Exemple de code permettant d’activer cette fonctionnalité :  

Lanceur

   

Code XAML

 

  
<UserControl x:Class="SLNotifications.MainPage"
			 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
			 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

	<Grid x:Name="LayoutRoot"
		  Background="White">
		<Button x:Name="NotifyButton"
				Content="Notifier"
				Click="NotifyButton_Click"
				HorizontalAlignment="Center"
				VerticalAlignment="Center" />
	</Grid>
</UserControl>

 

Code behind

 

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

namespace SLNotifications
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void NotifyButton_Click(object sender, RoutedEventArgs e)
        {
            NotificationWindow notify = new NotificationWindow()
            {
                Width = 300,
                Height = 90,
                Content = new MyNotifyWindow()
                {
                    DataContext = "Exemple de texte pour la notification, normalement on devrait créer une classe avec plus d'informations, ceci est juste un test."
                }
            };

            notify.Show(3000);
        }
    }
}

 

Contrôle de notification customisé

L’API de notification demande à afficher un controle  au sein de la pop up, dont voici un exemple :

<UserControl x:Class="SLNotifications.MyNotifyWindow"
			 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
			 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Grid Height="90"
		  HorizontalAlignment="Center"
		  VerticalAlignment="Center"
		  Width="300">
		<Rectangle Fill="#FF618DEC"
				   Stroke="White">
			<Rectangle.Effect>
				<DropShadowEffect Opacity="0.5"
								  ShadowDepth="0" />
			</Rectangle.Effect>
		</Rectangle>
		<TextBlock HorizontalAlignment="Left"
				   VerticalAlignment="Top"
				   TextWrapping="Wrap"
				   Margin="5"
				   Foreground="White"
				   Text="{Binding}" />
		<Path Stretch="Fill"
			  StrokeThickness="0"
			  Data="M0,0 L300,0 C191.8456,13.650899 91.632263,43.223179 0,90 z"
			  UseLayoutRounding="False"
			  Margin="1">
			<Path.Fill>
				<LinearGradientBrush EndPoint="0.5,1"
									 StartPoint="0.5,0">
					<GradientStop Color="#59FFFFFF"
								  Offset="0" />
					<GradientStop Color="#19FFFFFF"
								  Offset="1" />
				</LinearGradientBrush>
			</Path.Fill>
		</Path>
	</Grid>
</UserControl>

Exécution

Pensez à activer le mode OOB et à installer l’application (sinon cela ne fonctionnera pas)

Simple et pratique si vous en avez besoin dans vos applications OOB !

Code source SLNotifications.zip

Publicités
Catégories :Silverlight, Silverlight 4

[SL4] : Utilisation du WebBrowser

Autre nouveauté de la Beta de Silverlight 4 est le WebBrowser qui manquait cruellement pour pouvoir afficher du contenu HTML au sein de Silverlight.

Avant de vous décevoir, ne pensez pas que tout est possible… ceci n’est utilisable qu’en mode OOB ! Autant dire que cela va en décevoir plus d’un !

Toutefois regardons comment celui ci se comporte

Voici un exemple de code XAML permettant de saisir une URL ou un contenu HTML :

<UserControl x:Class="SL4Html.MainPage"
			 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
			 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

	<Grid x:Name="LayoutRoot"
		  Background="White">
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto" />
			<RowDefinition />
		</Grid.RowDefinitions>
		<Grid.ColumnDefinitions>
			<ColumnDefinition />
			<ColumnDefinition Width="Auto" />
		</Grid.ColumnDefinitions>
		<!--HTML INDICATIONS-->
		<TextBox x:Name="Url"
				 Margin="3" />
		<StackPanel Grid.Column="1"
					Orientation="Horizontal"
					Margin="3">
			<RadioButton x:Name="HtmlString"
						 Content="Chaine HTML"
						 GroupName="HtmlMode"
						 VerticalAlignment="Bottom" />

			<RadioButton x:Name="HtmlUrl"
						 Content="Url"
						 IsChecked="True"
						 GroupName="HtmlMode"
						 VerticalAlignment="Bottom" />

			<Button x:Name="SearchButton"
					Content="Go !"
					Click="SearchButton_Click"
					VerticalAlignment="Bottom"
					Margin="5,0,0,0" />
		</StackPanel>

		<!--HTML VIEWER-->
		<WebBrowser x:Name="Browser"
					Grid.Row="1"
					Grid.ColumnSpan="2" />
	</Grid>
</UserControl>

Ainsi que le code behind associé


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

namespace SL4Html
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void SearchButton_Click(object sender, RoutedEventArgs e)
        {
            if (HtmlUrl.IsChecked.Value == true)
            {
                Uri computedUri = null;

                if (Uri.TryCreate(Url.Text, UriKind.RelativeOrAbsolute, out computedUri))
                {
                    try
                    {
                        Browser.Navigate(computedUri);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                }
                else
                {
                    MessageBox.Show("Url non valide");
                }
            }
            else
            {
                Browser.NavigateToString(Url.Text);
            }
        }
    }
}

 

Exécution en mode non OOB

cela de marche pas comme nous l’avions vu au début de l’article !image

Exécution en mode OOB

pour cela faites clic droit sur l’application et installez l’application sur votre ordinateur

 image

Un message va apparaitre, cliquez “Install”

image

Ainsi nous pouvons afficher du HTML dans silverlight (ainsi que des plug ins additionnels comme Flash).

image

Mais aussi afficher du contenu HTML directement

image

Code source SL4Html.zip

Catégories :Silverlight, Silverlight 4

[SL4] : Utilisation du TextTrimming

SL4Text.zipUne des nouveautés de cette Beta est la possibilité d’utiliser la propriété TextTrimming que l’on peut trouver dans les TextBlock par exemple. Celle-ci permet de raccourcir le texte en affichant “…” en fin de texte. Ceci existait en WPF mais manquait cruellement à Silverlight.

Voici les deux valeurs disponibles actuellement :

  • None : n’effectue aucune troncature
  • WordEllipsis : effectue une troncature au mot près

Il manque encore la valeur “CharacterEllipsis” présente en WPF permettant d’effectuer une troncature au caractère près.

Voici un exemple de XAML permettant de se faire une idée sois même :

<Grid x:Name="LayoutRoot"
		  Background="White">
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition />

		</Grid.RowDefinitions>

		<Slider x:Name="Xslider"
				Minimum="0"
				Maximum="500"
				Value="200" />
		<Slider x:Name="Yslider"
				Minimum="0"
				Maximum="500"
				Value="200"
				Grid.Row="1" />

		<Border BorderBrush="White"
				Background="White"
				BorderThickness="5"
				HorizontalAlignment="Center"
				VerticalAlignment="Center"
				Grid.Row="2">
			<Border.Effect>
				<DropShadowEffect Opacity="0.5"
								  ShadowDepth="0" />
			</Border.Effect>

			<Grid Width="{Binding ElementName=Xslider, Path=Value}"
				  Height="{Binding ElementName=Yslider, Path=Value}">
				<Grid.RowDefinitions>
					<RowDefinition Height="Auto" />
					<RowDefinition Height="Auto" />
					<RowDefinition />
				</Grid.RowDefinitions>
				<TextBlock Text="Post quorum necem nihilo lenius ferociens Gallus ut leo cadaveribus pastus multa huius modi scrutabatur."
						   Foreground="Black" />
				<TextBlock TextTrimming="WordEllipsis"
						   Text="Post quorum necem nihilo lenius ferociens Gallus ut leo cadaveribus pastus multa huius modi scrutabatur."
						   Foreground="Red"
						   Grid.Row="1" />
				<TextBlock TextTrimming="WordEllipsis"
						   TextWrapping="Wrap"
						   Text="Post quorum necem nihilo lenius ferociens Gallus ut leo cadaveribus pastus multa huius modi scrutabatur."
						   Foreground="Blue"
						   Grid.Row="2" />
			</Grid>
		</Border>
	</Grid>

Voici une capture d’écran du résultat final :

image

Par exemple, sur cette capture d’écran, on voit bien les petits point s’affichant sur la ligne rouge 🙂

Code source ici

Catégories :Silverlight, Silverlight 4

[SL4] : Utilisation de la WebCam

Une des nouveautés de Silverlight 4 est sans conteste l’ajout de la possibilité d’utiliser une WebCam. Or on pouvais craindre que celà soit aussi compliqué qu’en WPF mais il n’en est rien ! L’utilisation de celle-ci se fait en quelques lignes.

Dans cet article nous allons voir comment afficher la WebCam, de l’arrêter ainsi que de prendre des capture d’image et les afficher à l’écran. Par ailleur afin de faciliter son utilisation nous allons réaliser un CustomControl se chargeant de faire les routines d’initialisation pour nous ainsi que de nous fournir un panel de fonctionnalités pour piloter la WebCam.

Création du controle


/// <summary>
	/// Controle facilitant l'utilisation de la WebCam
	/// </summary>
	public class WebCamControl : Control
	{
		#region Membres
		private CaptureSource _captureSource = null;
		#endregion

		#region Ctors
		/// <summary>
		/// Crée une instance du controle facilitant l'utilisation de la WebCam
		/// </summary>
		public WebCamControl()
		{
			this.DefaultStyleKey = typeof(WebCamControl);

			_captureSource = new CaptureSource();
VideoDevices = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();
		}
		#endregion
	}

 
Puis nous allons rajouter des DependencyProperty nous permettant d’obtenir :

  • la liste des composants de capture vidéo
  • le composant vidéo actuellement sélectionné
  • si le controle est en cours de capture de vidéo
  • un brush contenant la video actuellement capturée

#region DPs
        /// <summary>
        /// Définit une DP de type ICollection contenant la liste des composant permettant de capturer de la vidéo
        /// </summary>
        public static readonly DependencyProperty VideoDevicesProperty = DependencyProperty.Register("VideoDevices", typeof(ICollection<VideoCaptureDevice>), typeof(WebCamControl), new PropertyMetadata(null));

 		/// <summary>
		/// Définit une DP de type Brush représendant la video actuellement capturée
		/// </summary>
		public static readonly DependencyProperty VideoProperty = DependencyProperty.Register("Video", typeof(VideoBrush), typeof(WebCamControl), new PropertyMetadata(new VideoBrush()));

		/// <summary>
		/// Définit une DP de type Brush représendant la video actuellement capturée
		/// </summary>
		public static readonly DependencyProperty IsCapturingProperty = DependencyProperty.Register("IsCapturing", typeof(Boolean), typeof(WebCamControl), new PropertyMetadata(false));

		/// <summary>
		/// Définit une DP de type VideoCaptureDevice représendant la source video actuellement sélectionnée
		/// </summary>
		public static readonly DependencyProperty CurrentVideoCaptureDeviceProperty = DependencyProperty.Register("CurrentVideoCaptureDevice", typeof(VideoCaptureDevice), typeof(WebCamControl), new PropertyMetadata(null, new PropertyChangedCallback(OnCurrentVideoCaptureDeviceChanged)));

		#endregion

#region Handlers
		private static void OnCurrentVideoCaptureDeviceChanged(object sender, DependencyPropertyChangedEventArgs e)
		{
			WebCamControl me = sender as WebCamControl;

			if (me != null)
			{
				if (me.IsCapturing)
				{
					me.StopCapture();

					if (me.CurrentVideoCaptureDevice != null)
					{
						me.StartCapture();
					}
				}
			}
		}
		#endregion
		#region Propriétées

		/// <summary>
        /// VideoDevices DependencyProperty. Obtient la liste des sources vidéo disponibles
		/// </summary>
        public ICollection<VideoCaptureDevice> VideoDevices
        {
            get
            {
                return (ICollection<VideoCaptureDevice>)GetValue(VideoDevicesProperty);
            }

            private set
            {
                SetValue(VideoDevicesProperty, value);
            }
        }

		/// <summary>
		/// Video DependencyProperty. Obtient le brush contenant la video actuellement capturée
		/// </summary>
		public VideoCaptureDevice CurrentVideoCaptureDevice
		{
			get
			{
				return (VideoCaptureDevice)GetValue(CurrentVideoCaptureDeviceProperty);
			}

			set
			{
				SetValue(CurrentVideoCaptureDeviceProperty, value);
			}
		}

		/// <summary>
		/// IsCapturing DependencyProperty. Détermine si on est en train de capturer la vidéo
		/// </summary>
		public Boolean IsCapturing
		{
			get
			{
				return (Boolean)GetValue(IsCapturingProperty);
			}

			private set
			{
				SetValue(IsCapturingProperty, value);
			}
		}

		/// <summary>
		/// Video DependencyProperty. Obtient le brush contenant la video actuellement capturée
		/// </summary>
		public VideoBrush Video
		{
			get
			{
				return (VideoBrush)GetValue(VideoProperty);
			}

			set
			{
				SetValue(VideoProperty, value);
			}
		}
		#endregion

 Une fois celà réalisé nous allons créer une fonction permettant de démarrer la capture vidéo si toutes les conditions sont remplies (un composant vidéo sélectionné).

Rien de bien compliqué la clé résidant dans le fait de penser de définir deux points :

  •  la source vidéo dans notre objet CaptureSource (_captureSource) par la source vidéo sélectionnée.
  • associé cette source au brush représentant la vidéo « Video.SetSource(_captureSource); »

Puis penser à débuter la capture vidéo via « _captureSource.Start(); » et la capture débute !

/// <summary>
		/// Démarre la capture de la vidéo sur la WebCam selectionnée
		/// </summary>
		public void StartCapture()
		{
			if ((_captureSource != null) && (CurrentVideoCaptureDevice != null) && (IsCapturing == false))
			{
				_captureSource.Stop();
				IsCapturing = false;

				_captureSource.VideoCaptureDevice = CurrentVideoCaptureDevice;

				if (Video == null)
					Video = new VideoBrush();

				//on définit la source de capture en tant que brush
				Video.SetSource(_captureSource);

				//si on a les droits on lance la capture
				if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
				{
					_captureSource.Start();
					IsCapturing = true;
				}
			}
		}

A ce stade nous avons possibilité d’afficher la vidéo, nous allon faire une méthode permettant de stopper la dite capture


/// <summary>
		/// Arrete la capture de la video de la WebCam sélectionnée
		/// </summary>
		public void StopCapture()
		{
			if (_captureSource != null)
			{
				_captureSource.Stop();

				Video = null;

				IsCapturing = false;
			}
		}

Pour montrer comment faire pour prendre une capture d’image de la vidéo en cours :

/// <summary>
		/// Réalise une capture d'une image de la WebCam
		/// </summary>
		/// <param name="callback"></param>
		public void TakeSnapShot(Action<WriteableBitmap> callback)
		{
			if ((_captureSource != null) && IsCapturing)
			{
				_captureSource.AsyncCaptureImage(callback);
			}
		}

A présent nous avons tout ce qu’il nous faut pour afficher de la vidéo au sein d’une application Silverlight 4 ! Nous allons voir comment l’utiliser !

Utilisation

Il faut tout dabord créer un style par défaut pour le controle dans generic.xaml par exemple :

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SL4HTML">
    <Style TargetType="local:WebCamControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:WebCamControl">
                    <Rectangle Fill="{TemplateBinding Video}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

 Et pour terminer créer une page permettant d’afficher la webcam ainsi que quelques boutons pour piloter celle-ci :

<UserControl x:Class="SL4HTML.MainPage"
			 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
			 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
			 xmlns:controls="clr-namespace:SL4HTML">

	<Grid x:Name="LayoutRoot"
		  Background="White">
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto" />
			<RowDefinition />
		</Grid.RowDefinitions>

		<Grid.ColumnDefinitions>
			<ColumnDefinition Width="Auto" />
			<ColumnDefinition />
		</Grid.ColumnDefinitions>

		<!--ACTIONS-->
		<StackPanel Orientation="Horizontal"
					Grid.ColumnSpan="2"
					Margin="3">
			<Button x:Name="Start"
					Content="Start"
					Click="Start_Click" />
			<Button x:Name="Stop"
					Content="Stop"
					Click="Stop_Click" />
			<Button x:Name="SnapShot"
					Content="Photo !"
					Click="Photo_Click" />
			<ComboBox ItemsSource="{Binding ElementName=WebCamControl, Path=VideoDevices, Mode=OneTime}"
					  SelectedItem="{Binding ElementName=WebCamControl, Path=CurrentVideoCaptureDevice, Mode=TwoWay}"
					  DisplayMemberPath="FriendlyName"
					  Width="300" />

		</StackPanel>

		<!--WEBCAM VIEW-->
		<Border BorderBrush="White"
				Background="White"
				BorderThickness="5"
				Grid.Row="1"
				Grid.Column="1"
				Margin="3">
			<Border.Effect>
				<DropShadowEffect ShadowDepth="0"
								  Opacity="0.5" />
			</Border.Effect>
			<controls:WebCamControl x:Name="WebCamControl" />
		</Border>

		<!--SNAPSHOTS-->
		<ListBox x:Name="PictureList"
				 ItemsSource="{Binding SnapShots, Mode=OneWay}"
				 ScrollViewer.VerticalScrollBarVisibility="Auto"
				 Grid.Row="1"
				 Margin="3">
			<ListBox.ItemTemplate>
				<DataTemplate>
					<Border BorderBrush="White"
							Background="White"
							BorderThickness="5">
						<Border.Effect>
							<DropShadowEffect ShadowDepth="0"
											  Opacity="0.5" />
						</Border.Effect>
						<Image Source="{Binding}"
							   Width="100"
							   Stretch="Uniform"
							   HorizontalAlignment="Center"
							   VerticalAlignment="Center" />
					</Border>
				</DataTemplate>
			</ListBox.ItemTemplate>

			<ListBox.Style>
				<Style TargetType="ListBox">
					<Setter Property="Background"
							Value="Transparent" />
					<Setter Property="Padding"
							Value="0" />
					<Setter Property="Template">
						<Setter.Value>
							<ControlTemplate TargetType="ListBox">
								<Border>
									<ScrollViewer Padding="0"
												  Background="Transparent">
										<ItemsPresenter />
									</ScrollViewer>
								</Border>

							</ControlTemplate>
						</Setter.Value>
					</Setter>
				</Style>
			</ListBox.Style>

		</ListBox>
	</Grid>
</UserControl>

 Et voici le code behind

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Collections.ObjectModel;

namespace SL4HTML
{
    public partial class MainPage : UserControl
	{
		#region Membres
		private ObservableCollection<WriteableBitmap> _snapShots = new ObservableCollection<WriteableBitmap>();
		#endregion

		#region Ctors
		public MainPage()
        {
            InitializeComponent();

			DataContext = this;
        }
		#endregion

		#region Propriétées
		public ObservableCollection<WriteableBitmap> SnapShots
		{
			get
			{
				return _snapShots;
			}
		}
		#endregion

		#region Handlers
		private void Start_Click(object sender, RoutedEventArgs e)
		{
			WebCamControl.StartCapture();
		}

		private void Stop_Click(object sender, RoutedEventArgs e)
		{
			WebCamControl.StopCapture();
		}

		private void Photo_Click(object sender, RoutedEventArgs e)
		{
			WebCamControl.TakeSnapShot((picture) =>
			{
				_snapShots.Insert(0, picture);
			});
		}
		#endregion
	}
}

Silence… Action !

En lancant votre application vous devrez sélectionner une WebCam et cliquer sur « Start »

image

Un message de sécurité apparaitra vous indiquant que le site souhaite afficher votre webcam :

image

Ces informations sont disponibles si vous faites clic droit sur le site « Silverlight » et l’onglet « Webcam / Mic »

image

Voici le résultat final 🙂 :

image

Catégories :Silverlight, Silverlight 4