Blog

posts from 2014

The hour of code

0 Comments
By Fons Sonnemans, 16-12-2014

Op vrijdag 12 december hebben we op het Varendonck-College in Asten ‘the hour of code’ georganiseerd. Ongeveer 50 leerlingen hadden zich hiervoor opgegeven. The ‘hour of code’ is een wereldwijd initiatief om leerlingen te betrekken bij de wereld achter de computer, het programmeren.

In het kader van de wereldwijde week van de informatica konden in meer dan 180 landen tientallen miljoenen leerlingen tegelijk online deelnemen aan ‘the hour of code’.

Samen met Gerard Verbrugge van Microsoft gaven we de Varendonck leerlingen een één uur durende introductie in de informatica, om hen de basispricipes van programmeren te leren.

De enthousiaste deelnemers behaalden allemaal een certificaat.


Foto: Rob Fritsen - Siris

Tags: Code, Speaker

'Twelve ways to make your apps suck less' presentation

0 Comments
By Fons Sonnemans, 21-10-2014

The Dutch and Belgium Windows and Windows Phone developers have organized the Lowlands Windows Phone Developer Day event on 18 October 2014. I have presented this 'Twelve ways to make your apps suck less' presentation. With this blog I like to share the slides and demo projects (download button below).

Twelve ways to make your apps suck less from Fons Sonnemans

I would like to thank Joost van Schaik, Nico Vermeir and Glenn Versweyveld for organizing this wonderful event.

Windows 8 XAML Tips - Trigger Behaviors

0 Comments
By Fons Sonnemans, 2-7-2014

I use Behaviors in my XAML apps all the time. I have already written a few blog post about this subject. In Silverlight and WPF there was a clear distinction between Actions, Triggers and Behaviors. Triggers are used to invoke an Action. You can use the EventTrigger, StoryBoardCompleteTrigger, KeyTrigger, TimerTrigger, PropertyChangedTrigger, DataTrigger and DataStoreTrigger. And you can easily write your own by using the Trigger 'New Item' template in Blend.

In the Windows 8.1 'Behavior SDK' the Triggers are replaced by Trigger Behaviors. You only get the DataTriggerBehavior and EventTriggerBehavior but you can write your own. With this blog post I will try to explain how to do this. I will use a TimerTriggerBehavior and a SwipeTriggerBehavior which you can use to execute actions when you active a swipe gesture on a UIElement.

TimerTriggerBehavior

Before I can explain my TimerTriggerBehavior I first have to re-introduce my Behavior<T> class which I use as a base class for all my behaviors.

public abstract class Behavior<T> : DependencyObject, IBehavior 
    where T : DependencyObject {

    [EditorBrowsable(EditorBrowsableState.Never)]
    public T AssociatedObject { get; set; }

    protected virtual void OnAttached() {
    }

    protected virtual void OnDetaching() {
    }

    public void Attach(DependencyObject associatedObject) {
        if (associatedObject == this.AssociatedObject || 
            DesignMode.DesignModeEnabled) {
            return;
        }

        this.AssociatedObject = (T)associatedObject;
        OnAttached();
    }

    public void Detach() {
        if (!DesignMode.DesignModeEnabled) {
            OnDetaching();
        }
    }

    DependencyObject IBehavior.AssociatedObject {
        get { return this.AssociatedObject; }
    }
}

The TimerTriggerBehavior class is derives from this Behavior<T> class and contains DispatcherTimer. It has a MilliSecondsPerTick and IsEnabled properties. The MilliSecondsPerTick property is used to set the Interval of the Property. The IsEnabled property is used to start and stop the timer. It is an DependencyProperty so you can DataBind it. In Tick event is subscribed in the OnAttached() method and unsubscribed in the OnDetached() method. The Timer_Tick() event handler calls the Execute() method which invokes all triggers. The class also contains an Actions DependencyProperty and a Execute() method and the class is decorated with the ContentPropertyAttribute. This will be used by Blend for Visual Studio to allow Drag&Drop of Actions onto the Behavior.

[ContentProperty(Name = "Actions")]
public class TimerTriggerBehavior : Behavior<DependencyObject> {

    private DispatcherTimer _timer = new DispatcherTimer();

    private int _millisecondPerTick = 1000;

    public int MilliSecondsPerTick {
        get { return _millisecondPerTick; }
        set {
            _millisecondPerTick = value;
            _timer.Interval = TimeSpan.FromMilliseconds(_millisecondPerTick);
        }
    }

    #region Actions Dependency Property

    /// <summary> 
    /// Actions collection 
    /// </summary> 
    public ActionCollection Actions {
        get {
            var actions = (ActionCollection)base.GetValue(ActionsProperty);
            if (actions == null) {
                actions = new ActionCollection();
                base.SetValue(ActionsProperty, actions);
            }
            return actions;
        }
    }

    /// <summary> 
    /// Backing storage for Actions collection 
    /// </summary> 
    public static readonly DependencyProperty ActionsProperty =
        DependencyProperty.Register("Actions",
                                    typeof(ActionCollection),
                                    typeof(SwipeTriggerBehavior),
                                    new PropertyMetadata(null));

    #endregion Actions Dependency Property

    protected void Execute(object sender, object parameter) {
        Interaction.ExecuteActions(sender, this.Actions, parameter);
    }

    protected override void OnAttached() {
        base.OnAttached();
        _timer.Tick += timer_Tick;
        if (this.IsEnabled) {
            _timer.Start();
        }
    }

    private void timer_Tick(object sender, object e) {
        this.Execute(this, null);
    }

    protected override void OnDetaching() {
        base.OnDetaching();
        _timer.Stop();
        _timer.Tick -= timer_Tick;
    }

    #region IsEnabled Dependency Property

    /// <summary> 
    /// Get or Sets the IsEnabled dependency property.  
    /// </summary> 
    public bool IsEnabled {
        get { return (bool)GetValue(IsEnabledProperty); }
        set { SetValue(IsEnabledProperty, value); }
    }

    /// <summary> 
    /// Identifies the IsEnabled dependency property. 
    /// This enables animation, styling, binding, etc...
    /// </summary> 
    public static readonly DependencyProperty IsEnabledProperty =
        DependencyProperty.Register("IsEnabled",
                typeof(bool),
                typeof(TimerTriggerBehavior),
                new PropertyMetadata(true, OnIsEnabledPropertyChanged));

    /// <summary>
    /// IsEnabled changed handler. 
    /// </summary>
    /// <param name="d">TimerTriggerBehavior that changed its IsEnabled.</param>
    /// <param name="e">DependencyPropertyChangedEventArgs.</param> 
    private static void OnIsEnabledPropertyChanged(DependencyObject d, 
                            DependencyPropertyChangedEventArgs e) {
        var source = d as TimerTriggerBehavior;
        if (source != null) {
            var value = (bool)e.NewValue;
            if (value) {
                source._timer.Start();
            } else {
                source._timer.Stop();
            }
        }
    }

    #endregion IsEnabled Dependency Property

SwipeTriggerBehavior

The SwipeTriggerBehavior has a Direction property which you can set the swipe direction which will trigger the Actions. The ManipulationCompleted event on the UIElement is used to detect the swipe gesture. The ManipulationCompletedRoutedEventArgs.Velocities.Linear.X and Y are used to check the direction. I use this Between() extension method to check it is between 0.3 and 100. These values work for me but maybe not for you. Maybe I should make these flexible using properties (next version).

[ContentProperty(Name = "Actions")]
public class SwipeTriggerBehavior : Behavior<UIElement> {

    /// <summary>
    /// Get/Sets the direction of the Swipe gesture 
    /// </summary>
    public SwipeDirection Direction { get; set; }

    #region Actions Dependency Property

    /// <summary> 
    /// Actions collection 
    /// </summary> 
    public ActionCollection Actions {
        get {
            var actions = (ActionCollection)base.GetValue(ActionsProperty);
            if (actions == null) {
                actions = new ActionCollection();
                base.SetValue(ActionsProperty, actions);
            }
            return actions;
        }
    }

    /// <summary> 
    /// Backing storage for Actions collection 
    /// </summary> 
    public static readonly DependencyProperty ActionsProperty =
        DependencyProperty.Register("Actions",
                                    typeof(ActionCollection),
                                    typeof(SwipeTriggerBehavior),
                                    new PropertyMetadata(null));

    #endregion Actions Dependency Property

    protected void Execute(object sender, object parameter) {
        Interaction.ExecuteActions(sender, this.Actions, parameter);
    }

    protected override void OnAttached() {
        base.OnAttached();

        this.AssociatedObject.ManipulationMode = 
            this.AssociatedObject.ManipulationMode | 
            ManipulationModes.TranslateX | 
            ManipulationModes.TranslateY;

        this.AssociatedObject.ManipulationCompleted += OnManipulationCompleted;
    }

    protected override void OnDetaching() {
        base.OnDetaching();
        this.AssociatedObject.ManipulationCompleted -= OnManipulationCompleted;
    }

    private void OnManipulationCompleted(object sender, 
                                        ManipulationCompletedRoutedEventArgs e) {

        bool isRight = e.Velocities.Linear.X.Between(0.3, 100);
        bool isLeft = e.Velocities.Linear.X.Between(-100, -0.3);

        bool isUp = e.Velocities.Linear.Y.Between(-100, -0.3);
        bool isDown = e.Velocities.Linear.Y.Between(0.3, 100);

        switch (this.Direction) {
            case SwipeDirection.Left:
                if (isLeft && !(isUp || isDown)) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            case SwipeDirection.Right:
                if (isRight && !(isUp || isDown)) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            case SwipeDirection.Up:
                if (isUp && !(isRight || isLeft)) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            case SwipeDirection.Down:
                if (isDown && !(isRight || isLeft)) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            case SwipeDirection.LeftDown:
                if (isLeft && isDown) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            case SwipeDirection.LeftUp:
                if (isLeft && isUp) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            case SwipeDirection.RightDown:
                if (isRight && isDown) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            case SwipeDirection.RightUp:
                if (isRight && isUp) {
                    this.Execute(this.AssociatedObject, null);
                }
                break;
            default:
                break;
        }
    }
}

public enum SwipeDirection {
    Left,
    Right,
    Up,
    Down,
    LeftDown,
    LeftUp,
    RightDown,
    RightUp,
}

This class also contains an Actions DependencyProperty and an Execute() method. Just like the TimerTrigger. I have tried to place them in an abstract base class TriggerBehavior<> but that caused problems in Blend. You couldn't drop an action on the Triggers deriving from this class. So I have chosen to have some duplicate code.

Triggers Demo Project

To demonstrate these behaviors I have written this 'Triggers Demo' project. I Blend for Visual Studio I have dropped a TimerTriggerBehavior onto the root Grid element of the MainPage.

On the TimerTriggerBehavior I have dropped a PlaySoundAction. The Source of this action is set to a Click.wav which I added to the \Assets\Sounds folder of the project.

The Grid also contains a ToggleSwitch. The IsOn property is databound to the IsEnabled property of the timer trigger.

<ToggleSwitch Header="TimeTrigger"
                HorizontalAlignment="Left"
                Margin="114,-6,0,0"
                Grid.Row="1"
                VerticalAlignment="Top"
                OnContent="Enabled"
                OffContent="Disabled"
                IsOn="{Binding IsEnabled, ElementName=MyTimerTrigger, Mode=TwoWay}" />

I have dropped the SwipeTriggerBehavior 4 times on a blue Grid. Each with a different Direction: Up, Down, Left, Right. Inside each trigger I have dropped a ChangePropertyAction. The Value of the Text property of a TextBlock is set to the direction

<Grid Grid.Row="2"
        Margin="120,0,40,40"
        Background="#0096FF">

    <Interactivity:Interaction.Behaviors>
        <Behaviors:SwipeTriggerBehavior Direction="Up">
            <Core:ChangePropertyAction PropertyName="Text"
                                        TargetObject="{Binding ElementName=tbDemo}"
                                        Value="Up" />
        </Behaviors:SwipeTriggerBehavior>
        <Behaviors:SwipeTriggerBehavior Direction="Down">
            <Core:ChangePropertyAction PropertyName="Text"
                                        TargetObject="{Binding ElementName=tbDemo}"
                                        Value="Down" />
        </Behaviors:SwipeTriggerBehavior>
        <Behaviors:SwipeTriggerBehavior Direction="Left">
            <Core:ChangePropertyAction PropertyName="Text"
                                        TargetObject="{Binding ElementName=tbDemo}"
                                        Value="Left" />
        </Behaviors:SwipeTriggerBehavior>
        <Behaviors:SwipeTriggerBehavior Direction="Right">
            <Core:ChangePropertyAction PropertyName="Text"
                                        TargetObject="{Binding ElementName=tbDemo}"
                                        Value="Right" />
        </Behaviors:SwipeTriggerBehavior>
    </Interactivity:Interaction.Behaviors>

    <TextBlock Margin="50"
                HorizontalAlignment="Center"
                VerticalAlignment="Top"
                Style="{StaticResource HeaderTextBlockStyle}"
                Text="Swipe Up, Down, Left or Right" />

    <TextBlock x:Name="tbDemo"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Style="{StaticResource HeaderTextBlockStyle}" />

</Grid>

The result is a Page in which you hear a click sound play every 2 seconds. You can turn the sound off using the ToggleSwitch. If you swipe the blue box the swipe direction is shown in the center of this box.

Closure and download

I hope you like my solution. Feel free to use it in your projects. You can download the sample project below.

Cheers,

Fons

Events and code examples

0 Comments
By Roy Janssen, 2-7-2014

The last couple of months I have been speaking at a couple of events. For those who visited these events or for those who want to know more about the subject I will give a brief summary of the talks and post the slides / sample code here for you.

Azure mobile services

At the StoreAppsUG end of februari and at the SDN event last march I have been talking about Azure mobile services. In this talk I explained how to use Azure mobile services in combination with Windows 8 and Windows Phone 8. The example I have build for this is a clean example on how to do this in a simple way. You can find the slides (in Dutch) and example code here:

- Slides 

- Example code 

Kinect for Windows v2

At the TechDays in the Netherlands last april I have been talking about the new Kinect for Windows v2. As a participant in the Developer preview I had early access to the hardware and SDK. During this talk I showed a lot of the possibilities of the new Kinect for Windows sensor. You can watch my presentation online at the Channel 9 site.

Connecting hardware to Windows Phone 8

At the SDN event last june I spoke about connecting hardware to a Windows Phone 8 application. During this session I showed how you can connect and control Arduino hardware with your own Windows Phone 8 application. The Arduino hardware featured a lot of nice shining LED lights with the use of the Windows Phone application you could decide which to turn on or off. And even select the color of the RGB LED's. For now I'm only sharing the slides (in Dutch) since the code needs a little bit of cleaning up. But if you are interested in the rough code please contact me.

- Slides 

Tags: TechDays

MVP Windows Platform Development

0 Comments
By Fons Sonnemans, 1-7-2014

Vandaag ben ik voor de 2de keer uitgeroepen tot Microsoft Most Valuable Professional (MVP) op het gebied van Windows Platform Development. De titel Microsoft MVP wordt uitsluitend toegekend aan geselecteerde specialisten die zich actief inzetten voor een community rondom een Microsoft product. Microsoft beloont deze personen voor hun inzet en hulp aan de gemeenschap door middel van de titel MVP.

Microsoft MVP Logo

Tags: MVP

TechDays 2014 videos and presentations

0 Comments
By Fons Sonnemans, 31-5-2014

Op 16 en 17 april heb ik weer bij het TechDays 2014 event van Microsoft een aantal sessies gepresenteerd. Via deze blog wil ik de videos en presentaties met u delen.

What’s new in XAML and Tooling for Windows 8.1?

Channel 9 Video

SlideShare presentatie

Making money with Apps

Channel 9 Video

SlideShare presentatie

Designing XAML Apps using Blend for Visual Studio 2013

Channel 9 Video

SlideShare presentatie

 

Cheers,

Fons

Tags: TechDays, Apps, Blend, XAML

Windows 8.1 XAML Style for an AccentButton

0 Comments
By Fons Sonnemans, 14-4-2014

When you create a XAML application in Windows 8.1, you get a few built-in styles for TextBlock controls, such as: HeaderTextBlockStyle, TitleTextBlockStyle and SubtitleTextBlockStyle. Unfortunately there is no AccentButtonStyle. An AccentButton is a button with a special accent background color. I thought I’d try to create this Style. You can apply this Style to a Button. Optionally, you can set the Background property of the Button to a custom color.

AccentButtons sample

In the above example I have two StackPanels; the first with the RequestedTheme set to Dark, the second to Light. All Buttons in the StackPanel have the AccentButtonStyle. The bottom buttons have no Background property set. The 'Disabled' buttons have an IsEnabled property set to false.

<Page x:Class="AccentButtonDemo.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="using:AccentButtonDemo"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
              RequestedTheme="Dark">
            <TextBlock Style="{StaticResource SubtitleTextBlockStyle}"
            <StackPanel HorizontalAlignment="Center"
                        VerticalAlignment="Center">
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="Red"
                        Content="Red"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="Blue"
                        Content="Blue"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="LightGray"
                        Content="Gray"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="Blue"
                        Content="Disabled Blue"
                        IsEnabled="False"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Content="Default"
                        Style="{StaticResource AccentButtonStyle}" />
            </StackPanel>
        </Grid>
        <Grid Grid.Column="1"
              Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
              RequestedTheme="Light">
            <StackPanel HorizontalAlignment="Center"
                        VerticalAlignment="Center">
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="Red"
                        Content="Red"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="Blue"
                        Content="Blue"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="LightGray"
                        Content="Gray"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="Blue"
                        Content="Disabled Blue"
                        IsEnabled="False"
                        Style="{StaticResource AccentButtonStyle}" />
                <Button HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Content="Default"
                        Style="{StaticResource AccentButtonStyle}" />
            </StackPanel>
        </Grid>

    </Grid>
</Page>

AccentButtonStyle

The AccentButtonStyle is distributed in a resource dictionary through NuGet to make it easy to add it to your project and apply to your buttons. You will have to add this AccentButton.xaml ResourceDictionaries to the MergedDictionaries of your app.xaml or your pages or your controls.

<Application
    x:Class="AccentButtonDemo.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AccentButtonDemo">
	<Application.Resources>
        
		<ResourceDictionary>

            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="AccentButton.xaml" />
			</ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>
        
	</Application.Resources>

</Application>

 

Closure and download

I hope you like my solution. You can download the sample project below.

Cheers,

Fons

Tags: XAML, Windows 8

All postings/content on this blog are provided "AS IS" with no warranties, and confer no rights. All entries in this blog are my opinion and don't necessarily reflect the opinion of my employer or sponsors. The content on this site is licensed under a Creative Commons Attribution By license.