Category Archives: WPF

Bing RESX .NET Helper

I’m working on one consulting project in Silverlight and it had lots of localization features to be done, I had to construct the English language so that was easy. After that it was the turn for converting this RESX to 4 other languages, By the thought of doing it line-by-line I was more sleepy and lazy!

I did remember that once Dr. Don Syme had shown some samples of using Bing translator in JAOO tutorials. Quickly took that sample source and looked over it for 5 mins to get this working in this use case. Then it hardly took 20 mins to put up a script file and get my work done, that was the sweet spot, I did the below things,

  • Connected to BING API service “async”hronously
  • Read from the resources txt file
  • Passed each line to BING for translating
    • Each request is a parallel execution
    • Used async continuations to process out the results

That’s it, so it just took 20 mins and saved me the whole day’s work! I’m pretty sure most .NET apps have requirement of having it localized in various languages, this is one way to get your work done. You can take a look at the source code in github, https://github.com/fahadsuhaib/FSharpTools. Check out the readme to know how to use it.

-Fahad

You can follow me on Twitter – @fahadsuhaib

Advertisements

F# Quotations for INotifyPropertyChanged

I was wanting to use F# quotations with INotifyPropertyChanged for quite sometime now, Since I’m working on pure usage of F# in WPF and Silverlight this is one part that would help using F# with Visual Studio. There are lots of ViewModelBase implementation in C# that utilizes the LINQ expressions when you want to declare CLR properties. The LINQ Expression<Func> allows you to write strongly typed code in C# for defining the property,

private object selectedItem = null
public object SelectedItem
{
	get{ return this.selectedItem; }
	set
	{
		if(this.selectedItem != value)
		{
			this.selectedItem = value;
			this.OnPropertyChanged(() => this.SelectedItem)
		}
	}
}

The above code uses a strongly-typed OnPropertyChanged method that in-turn parses out the property name and passes that to the INotifyPropertyChanged interface.

Now that I’m officially working on full-time F# work, I was happy to get this done. Below code shows the ViewModelBase implementation utilizing the F# quotations,

open System
open System.Collections.ObjectModel
open System.ComponentModel
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

type ViewModelBase() =
    let propertyChanged = new Event<_, _>()
    let toPropName(query : Expr) = 
        match query with
        | PropertyGet(a, b, list) ->
            b.Name
        | _ -> ""

    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChanged.Publish

    abstract member OnPropertyChanged: string -> unit
    default x.OnPropertyChanged(propertyName : string) =
        propertyChanged.Trigger(x, new PropertyChangedEventArgs(propertyName))

    member x.OnPropertyChanged(expr : Expr) =
        let propName = toPropName(expr)
        x.OnPropertyChanged(propName)

To use the above, You need to inherit the ViewModelBase to your custom type and then call the OnPropertyChanged method with the F# quotations. Below is an example showing how to declare the same “SelectedItem” property in F#,

    let mutable selectedItem : obj = null

    member x.SelectedItem
        with get() = selectedItem
        and set(v : obj) = 
            selectedItem <- v
            x.OnPropertyChanged(<@ x.SelectedItem @>)

The F# quotations are wrapped around <@@> block, this is the syntax in F#. Now you get full intelli-sense with Visual Studio too,

image

Also, added this in the F# snippets site here.

Hope this helps.

-Fahad

F#– WPF Component Development

This post will only deal about using F# for WPF custom component development; it is considered that the user has already knowledge about WPF custom control development.

The current F# support for VS2010 is lagging in some ways,

· Can’t create a folder, this directly affects the way we can define the generic.xaml file.

· XAML -> BAML conversion with MSBuild task

We can do workarounds in both the cases and make component development using F# language and that is what we are going to discuss here. If there is any other better way to go for it, do let me know in your comments.

Creating Folders in an F# project

Till the F# team include this support in VS2010 we need to do the below workaround,

· Edit the .fsproj in Notepad.

· Add the below line in <ItemGroup>

.fsproj code

<Resource Include="Themes\generic.xaml" />

<Compile Include=”NewFolder\somefile.fs” />

XAML to BAML conversion through code

WPF has an API Application.LoadComponent(Uri) which loads a resource, although it is a bit slow. For a WPF component to load its inner template, it requires the generic.xaml file to be loaded when the control is initialized. In WPF C# custom control library, the below code does that automatically,

C# Code

public class CustomControl1 : Control

{

static CustomControl1()

{

DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));

}

}

Or we can just have the DefaultStyleKey overridden in the constructor,

C# Code

public class CustomControl1 : Control

{

public CustomControl1()

{

this.DefaultStyleKey = typeof(CustomControl1);

}

}

F# Solution

BAML conversion doesn’t work in F# because the MSBuild targets project for F# has issues when building the generic.xaml as a “Page” element.

On further investigation, I found that we can manually do the steps through code and make the control apply the template defined in XAML. Below are the steps that needs to be done,

1. Override the “DefaultStyleKey” property,

do this.DefaultStyleKey <- typeof<WatermarkTextBox>

2. Load the resource file and merge it to the control’s resources collection,

let resourceDict = Application.LoadComponent(new Uri("/FSharp.SampleControls.Wpf;component/Themes/generic.xaml", System.UriKind.Relative)) :?> ResourceDictionary

do this.Resources.MergedDictionaries.Add(resourceDict)

This will ensure that the control template is implicitly set to the control, you also have the OnApplyTemplate() getting called when you override that method. That’s it; we have loaded the control template and enabled the custom control to load like a normal WPF component. I also tested by editing the control’s Style using Blend and that also worked,

clip_image002

The full test sample is available in this link. The project contains a simple implementation of a WatermarkTextBox as a WPF custom control; it also has a C# WPF application that uses it.

I have also prepared a simple F# WPF custom control library project, You can download that from this link. You have to place this in the “Project Templates” location,

Windows 7

C:\Users\{UserName}\Documents\Visual Studio 2010\Templates\ProjectTemplates

This should enable VS2010 to load the template.

F# “fun” with Windows Phone 7

 

Don syme announced the availability of F# for Windows Phone 7 (link). Daniel Mohl has a project template for F# apps that Don showed in the F# community demo (link).

Note: Anyone wanting to start off a project from scratch can download the project template that I created from here. This is a simple F# WP7 app template without the extra demo files.

As with my previous posts (long back, can’t find enough time these days), I ported the Stock ticker code base to WP7. The UI is pretty simple, It only has a ListBox to show the stock data. The ListBox has a custom ItemTemplate that defines the layout for the input data pulled over the web (Yahoo finance). The application also checks for network connectivity. Below is a snapshot,

image

This sample only pulls the stocks when you click the button, Since it is used in a phone, actual CEP kind of scenario would not be suitable, so keeping the updates in deferred mode. UI polishing + added features would make this a good app for the market store, what do you think? 😉

Sample with source code link.

-Fahad

Loading XAML from C# – HACK!!!!

Ever wondered how to convert XAML to C# or to load a huge XAML content from C#, this post will possibly give you the best workaround to load it :).

If you have large Brush values or large XAML content that you would want to instantiate and apply it dynamically thru C#, it is either you convert to string and use the XAML reader or convert everything to some equivalent C# code. One other way is you could put up the XAML content inside a resource dictionary and hook it into the generic.xaml file. For more info on generic.xaml you can check out creating control templates for WPF, which allows overriding templates through resource files.

Once you have the resource dictionary setup with the XAML content, Say as below,

<?xml version="1.0" encoding="utf-8"?>
<ResourceDictionary xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DrawingBrush x:Key="Asterisk">
        <DrawingBrush.Drawing>
            <DrawingGroup>
                <DrawingGroup.Children>
                    <GeometryDrawing Brush="#FF000000" Geometry="F1 M 416.193,288.721L 406.118,
300.568L 406.212,300.848L 421.043,297.863L 421.043,307.284L 406.118,304.673L 406.025,304.952L 
416.193,316.426L 407.891,321.277L 402.574,306.818L 402.387,306.911L 396.977,321.277L 388.954,316.426L 
398.936,304.766L 398.936,304.579L 384.29,307.284L 384.29,297.863L 398.749,300.755L 398.842,
300.568L 388.954,288.814L 397.257,284.057L 402.48,298.329L 402.667,298.329L 407.984,284.057L 416.193,
288.721 Z "/>
                </DrawingGroup.Children>
            </DrawingGroup>
        </DrawingBrush.Drawing>
    </DrawingBrush>
</ResourceDictionary>

The above is a Asterisk symbol drawn with brush values. You could then create a WPF control instance and use the brush value as a background. Lets do that for a Border control,

private static ResourceDictionary GetResourceDictionary()
{
    ResourceDictionary rd = new ResourceDictionary();
    rd.Source = GetXamlConvertedValue<Uri>("Window1;component/Themes/Generic.xaml");
    return rd;
}

The above code simply creates a new Resource dictionary with the specified URI path. The GetXamlConvertedValue is simply a utility function that converts the string into the appropriate instance using TypeConverter,

public static T GetXamlConvertedValue<T>(string value)
{
    var converter = TypeDescriptor.GetConverter(typeof(T));
    if (converter != null)
    {
        return (T)converter.ConvertFromInvariantString(value);
    }
    return default(T);
}

 

Now we get the ResourceDictionary and get the DrawingBrush using the key “Asterisk”,

public static Brush BackgroundBrush
{
    get
    {
        var rd = GetCellRendererDictionary();
        var brush = rd["Asterisk"] as Brush;
        return brush;
    }
}

 

That’s it, We can simply get the value and set it as a background to the Border control. Like so any other content can be placed inside the ResourceDictionary and access it thru the Key/Value pair.

 

-Fahad