Oct 17, 2011

Binding to Image Path in Isolated Storage

Bind Image Source to web address is not problem, it will works well... until You don't care about performance. Problem will appear if You want to cache images. Isolated storage is only way to store downloaded files in Silverlight not matter Browser or Windows Phone. Not so difficult to download image file from Internet and save to Isolated Storage, but how to use it in Silverlight Page?

Well, lets try to figure out. First define image converter:

  1. public class IsoImageConverter : IValueConverter    
  2. {    
  3.     //Convert Data to Image when Loading Data    
  4.     public object Convert(object value, Type targetType, object parameter,    
  5.         System.Globalization.CultureInfo culture)    
  6.     {    
  7.         var bitmap = new BitmapImage();    
  8.         try    
  9.         {    
  10.             var path = (string)value;    
  11.             if (!String.IsNullOrEmpty(path))  
  12.             {    
  13.                 using (var file = LoadFile(path))    
  14.                 {    
  15.                     bitmap.SetSource(file);    
  16.                 }    
  17.             }    
  18.         }    
  19.         catch    
  20.         {    
  21.         }    
  22.         return bitmap;    
  23.     }    
  24.     
  25.     private Stream LoadFile(string file)    
  26.     {    
  27.         using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())    
  28.         {    
  29.             return isoStore.OpenFile(file, FileMode.Open, FileAccess.Read);    
  30.         }    
  31.     }    
  32.         
  33.     public object ConvertBack(object value, Type targetType, object parameter,    
  34.         System.Globalization.CultureInfo culture)    
  35.     {    
  36.         throw new NotImplementedException();    
  37.     }    
  38. }  

Next define link in App.xaml for use in XAML code

  1. <local:IsoImageConverter x:Key="IsoImageCoverter"/>  

And finally bind to string path to Isolated Storage image file

  1. <Image Source="{Binding ImagePath, Converter={StaticResource IsoImageCoverter}}"/>  

Sep 28, 2011

Localize ToggleSwitch in Silverlight Toolkit

Read tons of blogs and questions and answers, but cannot get Localize ToggleSwitch in SilverLight Toolkit in my Windows Phone Application. So i decided to get my own way. My proposal based on DataTemplate for ToggleSwitch and ValueConverter. So let's go.

First add Localized Resource for our new On and Off string values:


Next step create ValueConverter:
  1. public class BoolToSwitchConverter : IValueConverter  
  2. {  
  3.     private string FalseValue = Resources.Off;  
  4.     private string TrueValue  = Resources.On;  
  5.   
  6.     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
  7.     {  
  8.         if (value == null)  
  9.             return FalseValue;  
  10.         else  
  11.             return ("On".Equals(value)) ? TrueValue : FalseValue;  
  12.     }  
  13.   
  14.     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
  15.     {  
  16.         return value != null ? value.Equals(TrueValue) : false;  
  17.     }  
  18. }  
Make our converter visible from XAML, adding glue code to Application Resources in App.xaml Add link to app namespace if you not do this before xmlns:local="clr-namespace:AppNamspace" And add resource code
  1. <Application.Resources>  
  2.     <local:BoolToSwitchConverter x:Key="Switch" />  
  3. </Application.Resources>  
And finally override DataTemplate on our ToggleSwitch:
  1. <toolkit:ToggleSwitch x:Name="MySwitch" Header="Localized Switch">  
  2.     <toolkit:ToggleSwitch.ContentTemplate>  
  3.         <DataTemplate>  
  4.             <ContentControl HorizontalAlignment="Left"   
  5.                 Content="{Binding Converter={StaticResource Switch}}"/>  
  6.         </DataTemplate>  
  7.     </toolkit:ToggleSwitch.ContentTemplate>  
  8. </toolkit:ToggleSwitch>  
Result:

Sep 26, 2011

Localize Windows Phone 7 Styles

In process of localize silverlight application, usually, localized text wider than original english. In most cases it not a problem if You use StackPanel or other wrapping conrols, but sometimes width cannot be easely changed. In silverlight application You can use satellite assembly and put localized styles, and connect to page using MergedDictionary and ResourceDictionary.

Why cannot use same approach for Windows Phone application? There is many reasons:

  1. Windows Phone don't support satellite assemblies.
  2. Windows Phone don't care about xml:lang
  3. MergedDictionary degrade preformance
So try to use another approach. Define control, Button for example and apply default style
  1. <Button x:Name="MyStyledButton" Content="Button" Style="{StaticResource MyButton}"/>  
Then put general style in App.xaml

  1. <Style x:Key="MyButton" TargetType="Button">  
  2.     <Setter Property="Background" Value="#303030"></Setter>  
  3.     <Setter Property="BorderThickness" Value="0"></Setter>  
  4. </Style>  

Another bug in Windows Phone 7 that attribute BasedOn not supported, so we have to copy whole style to derived. Next step change name, adding -[lang code] to x:Key of style. So 'MyButton' will be 'MyButton-de' for example.

  1. <Style x:Key="MyButton-ru" TargetType="Button">  
  2.     <Setter Property="Background" Value="#FF8080"></Setter>  
  3.     <Setter Property="BorderThickness" Value="1"></Setter>  
  4. </Style>  

Next we'll add runtime code for loading language dependent styles.

  1. string lang = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;  
  2. // load localized style  
  3. Style style = (Style)App.Current.Resources["MyButton-" + lang];  
  4. if (style != null)  
  5. {  
  6.     MyButton.Style = style;  
  7. }  

In runtime we determine current UI language and try to load altered style. If found, apply new style, if not - hardcoded style will be used.

Sep 6, 2011

Load Image at Background Thread in Silverlight WP7

Load image at background thread in Silverlight Windows Phone 7 application, is that possible?

Usually when you try to use BitmapImage, Image, WriteableImage in other than UI thread, you'll get exception. This is because these classes are derived from  System.Windows.Threading.DispatcherObject, which is blocked access from other than UI thread. There exists an extension to WriteableBitmap, LoadJpeg, which is works fine in thread, but you have to create WriteableBitmap object on main UI thread.


  1. using System.Windows;  
  2. using System.Windows.Media.Imaging;  
  3. using System.IO;  
  4. using System.Threading;  
  5.   
  6. namespace ImageHelpers  
  7. {  
  8.     public delegate void ImageLoadedDelegate(WriteableBitmap wb, object argument);  
  9.   
  10.     public class ImageThread  
  11.     {  
  12.         public event ImageLoadedDelegate ImageLoaded;  
  13.   
  14.         public ImageThread()  
  15.         {  
  16.         }  
  17.   
  18.         public void LoadThumbAsync(Stream src, WriteableBitmap bmp, object argument)  
  19.         {  
  20.             ThreadPool.QueueUserWorkItem(callback =>  
  21.             {  
  22.                 bmp.LoadJpeg(src);  
  23.                 src.Dispose();  
  24.                 if (ImageLoaded != null)  
  25.                 {  
  26.                     Deployment.Current.Dispatcher.BeginInvoke(() =>  
  27.                     {  
  28.                         ImageLoaded(bmp, argument);  
  29.                     });  
  30.                 }  
  31.             });  
  32.         }  
  33.     }  
  34. }  


Using scenario:

  1. ImageThread imageThread = new ImageThread();  
  2.   
  3. private void Init()  
  4. {  
  5.     imageThread.ImageLoaded += LoadFinished;  
  6. }  
  7.   
  8. void LoadFinished(WriteableBitmap bmp, object arg)  
  9. {  
  10.     Imgage1.Source = bmp;  
  11. }  
  12.   
  13. void DeferImageLoading( Stream imgStream )  
  14. {  
  15.     // we have to give size  
  16.     var bmp = new WriteableBitmap(80, 80);  
  17.     imageThread.LoadThumbAsync(imgStream, bmp, this);  
  18. }  

Aug 25, 2011

Using WP7 Profiler

Windows Phone 7 SDK RC add exciting new feature to developers. After installed new developer tools I noticed Microsoft Windows Phone 7.1 Profiler in About menu of Visual studio 2010 for Windows Phone. Quick Googling give no results, but everything more easy than can looks.

Open Your WP7 project and look into Debug menu. You will see disabled (probably not) menu item Start Windows Phone Performance Analysis


To enable this item You have to switch Your project target from Windows Phone 7.0 to 7.1 in Project -> Properties menu. So if Your application targeted current market, you have to make project clone prior profiling, cause You cannot switch back to 7.0.

When application targeted Mango You can open profiler. Choose options and click hyperlink Launch Application.


After working with application click Stop Profiling. After analysis You will see profiling results. Select timeline and it shows details.


Update: Finally found MSDN Page, describing WP7 Profiler

No more using of MSAF for WP7 Analytics

While looking for analytics for my WP7 application, i've found MSAF - Microsoft Silverlight Analytics Framework.

Project looks great, but first i figured out is have many assemblies and dependencies.

Making test application is almost impossible - lack of clear documentation. Samples also unclear and possible i never tried this framework, but fortunately i've found kodirer blog. Thanks to Mr. Rene - he has clearly described neccessary steps to work it out.

Sample app with simple static page works well, but when i add it to my panorama application i saw Crippling Performance Issue. Issue ticket contains attached "fixed" assembly, which is make issue not so sharp, but still noticable performance decrease.

I found years ago, that some MS Frameworks, written on best pattern practices is buggy and performance killers.

Only thing is needed is to call Google Analytics site once in application, so why it need to intrude in any kind of events in application. Even if will fixed for this particular issue i cannot be sure about all other cases.

So, it's time to write my own analytics tracker...

Aug 6, 2011

Handle OnClick Event in ListBox on Silverlight for Windows Phone 7

Generally on Windows Phone 7 using Silverlight You will use ListBox templates like this one

  1. <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items}" >  
  2.     <ListBox.ItemTemplate>  
  3.         <DataTemplate>  
  4.             <StackPanel Orientation="Horizontal" Margin="0,0,0,17"  
  5.                        MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">  
  6.                 <Image Height="150" Width="150" Source="{Binding ImageSource}" Stretch="UniformToFill" />  
  7.                 <StackPanel Width="311">  
  8.                     <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>  
  9.                     <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>  
  10.                 </StackPanel>  
  11.             </StackPanel>  
  12.         </DataTemplate>  
  13.     </ListBox.ItemTemplate>  
  14. </ListBox>  

But on touch based platform such as Windows Phone 7, MouseLeftButtonDown will trigger event, even if You try scroll ListBox content. Another aproach is to use ManipulationCompleted event. Event arguments have property named IsTapEvent, but in latest Silverlight SDK this property is declared as Protected. So You can see it in debugger at runtime, but cannot use in code.

What You can do is subscribe to ManipulationCompleted event, and check e.TotalManipulation for Scale and Transform properties equals zero.

  1. private void StackPanel_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)    
  2. {    
  3.     var zero = new Point(0,0);    
  4.     if( e.TotalManipulation.Scale == zero && e.TotalManipulation.Translation == zero )    
  5.         MessageBox.Show("gotcha!");    
  6. }    

Jul 8, 2011

Windows compatible keyboard layout for nano editor

This post is not about C#, but sometimes fortune bring You to some places, where You never been before. For example, may be You need to install Your .NET Web Service on Unix platform. Have You ever have nightmare to edit files in vim? But not all so bad.

Nano editor is one of convenient text editors in unix. If You ever have trouble with vim (I do) You could find nano editor very friendly. But unix people make difficult anything that can be very easy. Keyboard layout is unbelievable inconvenient... what authors smoking? Fortunately it can be easy fixed by .nanorc file. Symply make new file .nanorc in home directory with content followed below. It will make keyboard bindings almost same as on Windows.

After restart nano editor will use standard shortcuts - Ctrl-S for save, Ctrl-O for open files, Ctrl-C for copy, Ctrl-V for paste, etc. Although there is some problem with undo/redo. Seems undo shortcut is hardcoded to Alt-U and Alt-Y for redo.

~/.nanorc

set undo
set autoindent
set mouse

bind ^S writeout main
bind ^O insert main
bind ^G gotoline main
bind ^X cut main
bind ^V uncut main
bind ^C copytext main
bind ^H replace main
bind ^Q exit main
bind ^Z undo main
bind ^F whereis main
bind F3 searchagain main
bind F1 help main

Updated layout:

Ctrl-Q leaved for exit for compatibility
Cut line replaced by Ctrl-Y, which is common for cut line

set undo
set autoindent
set mouse

bind ^S writeout main
bind ^O insert main
bind ^G gotoline main
bind ^Y cut main
bind ^V uncut main
bind ^C copytext main
bind ^H replace main
bind ^Z undo main
bind ^F whereis main
bind F3 searchagain main
bind F1 help main

May 10, 2011

Integrate NUnit with Visual Studio Express

NUnit Test Application

C# Project Template

Integrated tests with Visual Studio, including Visual C# Express version
Self contained NUnit console runner. Allow to write test fixtures and test, running from Visual Studio simply by pressing F5 (support test debugging), or Ctrl-F5 free run with results in console window. In case of test failure indicate by beep sound.

Contains essential NUnit modules to start test project. No external dependencies. Simply create new project, using NUnit Test Application template.

Download

download template

Links


http://www.nunit.org

Apr 30, 2011

Easy Localize WPF Application via Visual Studio Template

Background

Localizing a WPF application is not an easy task. Almost any article on the localization of WPF is replete with details and manual steps toimplementation a localized application.

Existing solutions

Localization using the utility LocBaml are described in the localization of Microsoft has lots of advantages, but difficult to maintain. André van heerwaarde in his article proposed to simplify this decision by the configured build step. He wrote an utility to merge the translated text fragments. However, in his article, still many manual steps.

Visual Studio Project Template

I propose to use a Localized WPF Application template, I've created to start working on a multilingual WPF application. Project created using this template already contains all the necessary tools for localization, as well as the maximum automates the localization process.
During application development, you add a new XAML file without having to worry about localization. Upon completion of the changes simply build project.