Archive

Posts Tagged ‘WPF’

Starting your PixelSense application efficiently : Loading Controls

May 12, 2013 Leave a comment

When you start to build application for the SUR40 and Microsoft PixelSense, all used to work really perfectly well on the simulator and your development PC. When you start to install and run your application directly on the device in Surface mode, you start to face a challenging but important issue:

Get your application started before the Surface Shell timeout

All of us as found the famous startup time-out handle by the Surface shell. It could happen that your application appears to never start in that mode or it start but not all the time.

Never block the main UI thread

The entry point of your Surface application is the main surface window, and this is also the main UI thread for your application. If you perform some long operation within the loading process of that main Window, you are blocking the main UI thread and you will definitely get the famous time-out message

How does it really works

A Microsoft Surface application must not block the UI thread for more than 5 seconds. If it does so, the system closes and tries to restart the unresponsive applications twice. If it must close the application a third time because of unresponsiveness, Surface returns to Launcher and does not try any further restarts.

Loading your application while using potentially long loading of controls

When you start to build an application, you usually start to fill up your SurfaceMainWindow.xaml grid with the different control that you think your need to load.
The following code snapshot shows that scenario:


Potentially Locked Main Surface windows loading process

<s:SurfaceWindow x:Class=”SurfaceAppStartup1.SurfaceWindow1″

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

xmlns:s=”http://schemas.microsoft.com/surface/2008&#8243;

Xmlns:controls=”clr-namespace:SurfaceAppStartup1.Controls”

Title=”SurfaceAppStartup1″

>

<Grid x:Name=”Content” Height=”Auto”>

<s:SurfaceScrollViewer x:Name=”_mainHScrollViewer” ScrollChanged=”_mainHScrollViewer_ScrollChanged”

Width=”{Binding Element Name=Main, Path=Width}”

PanningMode=”None”

HorizontalScrollBarVisibility=”Hidden”

VerticalScrollBarVisibility=”Hidden” DataContext=”{Binding}”>

<StackPanel x:Name=”AppPanel” Orientation=”Horizontal” Background=”Transparent” >

<!– Load background Window –>

<controls:BackgroundImage DataContext=”{Binding}”/>

<!– Load WordMapControl  –>

<controls:WorldMapControl/>

</StackPanel>

</s:SurfaceScrollViewer>

</Grid>

</s:SurfaceWindow>

From the sample above, you can see that we are instantiated directly in Xaml the loading of the WorldMapControl UserControl as <controls:WorldMapControl/>. In this case if the loading time that that control is longer than plan your main UI thread will be block and you will get the Surface Shell Time-Out.

Solution : Use of Content control and Binding

From the sample above, we simply replace the <controls:WorldMapControl/> by the code below :

<ContentControl DataContext=”{Binding Source={StaticResource Locator}, Path=WorldMapViewModelStatic}”

Content=”{Binding MapControl, UpdateSourceTrigger=PropertyChanged}” />

You can guess from code above that we are using binding and an MVVM pattern to reach our goal. By doing so, the main UI thread will not be block during the loading of the control. Instead it will prepare a Content control that will have its Content property bind to a MVVM property named MapControl. When the MapControl property change, the control will be injected in the ContentControl.

What to do then while my user will wait for control to load?

This is a really interesting question and there are different approach. First avoid using a simple loading screen without adding value for the user. Remember that as soon as a Surface application has started, the application is interactive and user expect to do something with it:

  1. Provide simple content information in relation with your application that users can already explore
  2. Indicate visually that remaining content are currently loading
  3. When the remaining controls have completed and the full application is ready,bring attention to users with visual component or effect that something more can be done

Important :

When all your application initialization content is done, your application must call the Microsoft.Surface.ApplicationServices.SignalApplicationLoadComplete method to dismiss the opening activity when the application is ready to appear.

You can download sample project which illustrate this from the msdn code sample.

Hoping this small post will be helpfull for you.

Sample Nested ScrollViewer interaction design

November 18, 2012 4 comments

In one of my project on a Samsung SUR40 with Microsoft PixelSense, I was facing to an interesting interaction design based on different information groups needed to be logically displayed and accessible in a natural way.

The final idea is illustrated by the picture below:

The visual tree

The most external brown rectangle is a panorama panel which should be able to be scroll in both horizontal directions in order to have freely access to child group control. When the user will reach is interesting group of information represented by the blue rectangle, inside information, in my scenario was to be able to scroll vertically the information. And here comes the interaction logic from where you have nested scrollable control.

In order to reach my goal the layout has been define by the following tree, but you could adjust in according to your need.

Control architecture

The resulting XAML of the main panel :

 

The resulting XAML of the group control :

 

Interaction & design key point:

From the interaction that we have setup and as mentioned earlier, we need to get it smooth, logic and natural. If we look closer to the inside group control, they are nothing much that SurfaceList box control with have been define to handle vertical scroll only in that sample. So in each group control we will be able to naturally scroll for vertical data.

But then how can we scroll the panel horizontally?

The first answer to this question: Easy we just need to scroll the whole panel with the help of the most outside scroll viewer. That is correct. But asking the user to scroll the whole panel by placing is finger at the bottom narrow space of the control, do you thing user will all think of that? Absolutely not.

The best approach and most natural way would be that users initiating a horizontal scroll from any group control should be able to start the main panel to scroll, as illustrate bellow:

Apparently should be possible without any trouble but in fact the scroll does not happen.

As we have seen in our layout, each control group embedded a scrollviewer set for vertical scrolling. Horizontal scroll is disabling, but even if it would be enable it will scroll the group control content only. So why does this not work?

The reason came from the fact that the touch is capture by the scrollwiewer and the handle is set to true, so the event in not propagated up to the visual tree.

Nested scrollViewer behavior comes to the rescue

In order to allows that interaction, we have define a nested scrollviewer behavior class which pass to the parent scrollviewer control interaction which is not dedicated to its child.

By adding this behavior to each group control scrollviewer, the gesture will be passing to the parent scrollviewer which is the main panel and you will have a natural scrolling effect.

You can download the project from msdn sample here.
The sample include MVVM pattern

How to attached an MVVM EventToCommand to an Attached event

August 23, 2012 6 comments

In my daily lif e of developer, I am using every time the MVVM Light tool kit which offer me flexibility and set up of the model in an easy and efficient way. On a recent Microsoft PIxelSense project I get the need to bind my MVVM to an attached event. So at first I thought it should be similar as a normal event so I start to setup my triggers as follow:

<s:SurfaceSlider Name=”timelineSlider” Grid.Row=”1″ >
<i:Interaction.Triggers>
  
<helpers:RoutedEventTrigger RoutedEvent=”Thumb.DragStarted” >
    
<cmd:EventToCommand Command=”{Binding Mode=OneWay, Path=SeekStartedCmd}” PassEventArgsToCommand=”True” />
</helpers:RoutedEventTriggers>

The code above, is based on a player way I need to use a slider for a Seek method. So to track the change on the slider, one of the events I need to catch was the one from the Thumb.

At first look it sounds promising, no error, and code run perfectly but the event get not catch.

 We can’t invoke command on attached events. For example we can’t invoke command on Thumb.DragStarted

 How to handle attached event:

After some research on the web and shaking different type of information I came across the following class which will help to solve my issue. We create a new trigger which fires on attached event by inheriting EventTriggerBase<T> class.

namespace Solatys.Helpers
{

 publicclassRoutedEventTrigger : EventTriggerBase<DependencyObject>
    {
        RoutedEvent _routedEvent;
        publicRoutedEvent RoutedEvent
        {
            get
            {
                return _routedEvent;
            }
            set { _routedEvent = value; }
        }

        public RoutedEventTrigger() { }
        protected override void OnAttached()
        {
            Behavior behavior = base.AssociatedObject asBehavior;
            FrameworkElement associatedElement = base.AssociatedObject asFrameworkElement; if (behavior != null)
            {
                associatedElement = ((IAttachedObject)behavior).AssociatedObject asFrameworkElement;
            } if (associatedElement == null)
            {
                thrownewArgumentException(“Routed Event trigger can only be associated to framework elements”);
            }
            if (RoutedEvent != null)
            {
                associatedElement.AddHandler(RoutedEvent, newRoutedEventHandler(this.OnRoutedEvent));
            }
        }

        void OnRoutedEvent(object sender, RoutedEventArgs args)
        {
            base.OnEvent(args);
        }

        protected override string GetEventName()
        {
            return RoutedEvent.Name;
        }
    }
}

 How to use it :

<s:SurfaceSlider Name=”timelineSlider” Grid.Row=”1″>
 
<i:Interaction.Triggers>
   <helpers:RoutedEventTrigger RoutedEvent=”Thumb.DragStarted” >
    <cmd:EventToCommand Command=”{Binding Mode=OneWay, Path=SeekStartedCmd}”
      PassEventArgsToCommand
=”True” />
  </i:Interaction.Triggers>
</s:SurfaceSlider>

 Happy coding

Categories: WPF Tags:

Change Thumb color style from a SurfaceListBox

May 28, 2012 1 comment

I have been ask recently in a post where to change the color and general style of surfaceListbox. Basically what will be affected if the ScrollViewer object within the SurfaceListbox. To do so the easiest way is as follow :

  1. Create an empty Surface project in VS2010
  2. Open your project withinh Expression Blend
  3. On your empty main windows add a SurfaceListbox control
  4. Right click on the Control and select EditTemplate -> Edit Copy
  5. You are now able to edit the template

The part in the template which is dedicated to the scroll bar is the following . Let’s take the sample of the vertical scrollbar

<!– ScrollBar Vert Thumb –>

<Style x:Key=”SurfaceScrollBarThumbStyle”

TargetType=”{x:Type s:SurfaceThumb}”

BasedOn=”{StaticResource SurfaceHitAreaBaseStyle}”>

<Setter Property=”Template”>

<Setter.Value>

<ControlTemplate TargetType=”{x:Type s:SurfaceThumb}”>

<ControlTemplate.Resources>

<Storyboard x:Key=”Touch”>

<DoubleAnimation Duration=”0:0:0.05″

Storyboard.TargetName=”Thumb”

Storyboard.TargetProperty=”Width”

To=”16″/>

<ThicknessAnimation Duration=”0:0:0.05″

Storyboard.TargetName=”Thumb”

Storyboard.TargetProperty=”Margin”

To=”-1,0,-1,0″ />

</Storyboard>

<Storyboard x:Key=”Release”>

<DoubleAnimation Duration=”0:0:0.1″

Storyboard.TargetName=”Thumb”

Storyboard.TargetProperty=”Width”

To=”14″/>

<ThicknessAnimation Duration=”0:0:0.1″

Storyboard.TargetName=”Thumb”

Storyboard.TargetProperty=”Margin”

To=”0,0,0,0″ />

</Storyboard>

</ControlTemplate.Resources>

<Grid x:Name=”Grid”

Background=”{TemplateBinding Background}”

SnapsToDevicePixels=”{TemplateBinding SnapsToDevicePixels}”>

<Rectangle x:Name=”Thumb”

Height=”Auto”

Width=”14″

HorizontalAlignment=”Stretch”

VerticalAlignment=”Stretch”

Fill=”{DynamicResource {x:Static s:SurfaceColors.ThumbEnabledBrushKey}}” />

</Grid>

<ControlTemplate.Triggers>

<Trigger Property=”s:TouchExtensions.AreAnyInputDevicesCapturedWithin”

Value=”True”>

<Trigger.EnterActions>

<BeginStoryboard Storyboard=”{StaticResource Touch}”/>

</Trigger.EnterActions>

<Trigger.ExitActions>

<BeginStoryboard Storyboard=”{StaticResource Release}”/>

</Trigger.ExitActions>

</Trigger>

<Trigger Property=”IsEnabled”

Value=”False”>

<Setter Property=”Fill”

TargetName=”Thumb”

Value=”{DynamicResource {x:Static s:SurfaceColors.ThumbDisabledBrushKey}}”/>

</Trigger>

</ControlTemplate.Triggers>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

From the template snipet above we are interresting on the bold section of it.
The background property of the grid element define tha color of the scroll bar.
The Fill property of the Rectangle child element of the grid represent the Thumb color.

Simply define your own style brush and reference them for this 2 properties

Hope it helps


								
Categories: SURFACE Tags: , , ,

Adding Custom Color to your Surface Contacts

March 29, 2012 Leave a comment

Sometimes it is is good to know also simple things under the cover that you would have never though to add to you app until a customer raise that question. The source of the issue was the fact that customer application background was build with quite light colors range and he was simply asking that it could be nice to be able to change the contact color on your surface application.

As all of us may know, for us it might be a useless thing but what customer want customer have.

So for those who want to provide the abilities to affect that contact colors here what you should do.

For that I will use a cool way which will differe from traditionnal code behind approach, instead will use direct binding:

  • Define a ressource entry of type string and name it ContactColor
  • Provide as a string value the exemple of #FFFFFF ( correspondign to White color)
  • From your main window xaml file add the following xaml name space :xmlns :props=”clr-namespace:MyApplication.Properties;assembly=MyApplication”
  • Enter the following line to your windows:TouchVisualizer.VisualizationColor1=”{Binding ContactColor, Source={x:Static props:Settings.Default}}” s:TouchVisualizer.VisualizationColor2=”{Binding ContactColor, Source={x:Static props:Settings.Default}}” s:TouchVisualizer.VisualizationColor3=”{Binding ContactColor, Source={x:Static props:Settings.Default}}”>

ContcatColor notify property is populated as follow from code behind :
/// The name of the visualization color setting in the config file.
private const string _ContactColorSetting = “NameOfressourceKey”;

System.Drawing.Color tempColor = System.Drawing.ColorTranslator.FromHtml(GetSetting(_ColorSetting, defaults));
ContactColor =Color.FromArgb(tempColor.A,tempColor.R, tempColor.G, tempColor.B);

An that’s it.

What this binding does is reading the value of the ressource property ContactColor which is bind to a ViewModel property ContactColor of my application and associate that color to each visualizer. By placing that color in a ressource, you can provide an easy way to access it through a configuration tool.

For more inofrmation on TouchVisualizer

A simple thing, will cool effect on your final app

Hoping you will find it interresting

Categories: SURFACE Tags: , , ,

Date and Time in WPF

November 17, 2011 Leave a comment

Recently, i was fighting with a date/Time interpretation which makes me a kind of crazy.The scenario was collecting data from a return dataset based on SQL serve table. When looking in that dataset, the date/Time format of dat fields was formatted correctly based on the culture I get set. But as long as the data was rendering by my WPF gridview, Date/Time value gets disply in different manner.

After browsing around I met Mike Danes on a forums which gets similar trouble.

When you convert a date time to string in code the current (correct) culture is used. However WPF doesn’t use the current culture, it takes the culture name from the Language property of the FrameworkElement and then gets the culture by using GetCultureInfoByIetfLanguageTag. This method returns a standard CultureInfo object, not the user customized version. This has been reported as a bug by Mike already.

To overcome this, it was needed to apply a converter to my date/Time column field.

I would never seen that problem if my users did not start to change cutsom settings of standard culture.

Hope it could save you time as well.
Thanks to Mike as well helping me isolate the issue

Categories: Uncategorized, WPF Tags:

Solatys recherche developpeur(s) .net, Wpf

September 14, 2011 Leave a comment

Solatys a affirmé sa phase de développement et recherche ses développeurs .Net, WPF afin de renforcer son équipe.

Vous avez toujours voulu exprimé votre créativite dans une technologie innovante mais n’avez pu le faire aujourd’hui?

En tant que Microsoft Surface Partner, nous vous offrons cette chance de participer avec nous à l’élaboration d’applications tactiles sous Microsoft Surface, tablettes et windows phone 7.
Vous vous reconnaissez et etes motivé à l’idée de nous rejoindre, alors contactez-nous sans plus attendre et faite partie de l’aventure.

Categories: SURFACE Tags: ,