5 people like it.

Simple F# ViewModel for Silverlight MVVM

Silverlight default architecture is Model-View-ViewModel. This code gives full design time support for Microsoft Expression Blend. The F# ViewModel is seen as strongly typed data source in the Blend UI. There are two properties binded to the view: HiLabel (OneWay data binding) and MyName (TwoWay data binding). ViewModel implements the INotifyPropertyChanged to support the binding. The view project (HelloApp) is made with Blend (by designers) and it is Silverlight 5.0 project. The view codebehind is c# file and it has only this.DataContext -assignment. The viewmodel project (HelloApp.ViewModel) is F# Silverlight 4.0 library. It is made with VS2010 and F# (by developers). It contains the logical functionality of the current view.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
83: 
//MainViewModel.fs
#light
//Expression Blend support: wrap to namespace, not module
namespace HelloAppViewModel

open System
open System.ComponentModel

type MainViewModel() =

    let mutable myname = ""
    
    let event = new Event<_,_>()
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = event.Publish
    
    member x.TriggerPropertyChanged(name)=
        event.Trigger(x, new PropertyChangedEventArgs(name))
    
    member x.MyName 
        with get() = myname
        and set t = 
                myname <- t
                x.TriggerPropertyChanged "MyName"
                x.TriggerPropertyChanged "HiLabel"

    member x.HiLabel = "Hello " + x.MyName + "!"

////---------------------------------------------------------------------------------------
////View codebehind: MainPage.xaml.cs
//
//using System.Windows.Controls;
//namespace HelloApp
//{
//	public partial class MainPage : UserControl
//	{
//		public MainPage()
//		{
//			  // Required to initialize variables
//			  InitializeComponent();
//            this.DataContext = new HelloAppViewModel.MainViewModel();
//		}
//	}
//}

////---------------------------------------------------------------------------------------
////View xaml: Mainpage.xaml
//<UserControl
//	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
//	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
//	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
//	xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
//	x:Class="HelloApp.MainPage"
//	Width="640" Height="480">
//
//	<Grid x:Name="LayoutRoot" Background="White" d:DataContext="{d:DesignData /SampleData/MainViewModelSampleData.xaml}">
//		<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Width="400">
//			<TextBlock TextWrapping="Wrap" Text="Input your name:"/>
//			<StackPanel Orientation="Horizontal">
//				<TextBox x:Name="MyNameTextbox" TextWrapping="Wrap" Text="{Binding MyName, Mode=TwoWay}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200">
//					<i:Interaction.Triggers>
//						<i:EventTrigger EventName="TextChanged">
//							<ei:ChangePropertyAction TargetName="HelloLabel" PropertyName="Visibility"/>
//						</i:EventTrigger>
//					</i:Interaction.Triggers>
//				</TextBox>
//				<Button Content="Hi!" HorizontalAlignment="Right" VerticalAlignment="Top"/>
//			</StackPanel>
//			<TextBlock x:Name="HelloLabel" TextWrapping="Wrap" Text="{Binding HiLabel}">
//				<i:Interaction.Triggers>
//					<i:EventTrigger>
//						<ei:ChangePropertyAction PropertyName="Visibility">
//							<ei:ChangePropertyAction.Value>
//								<Visibility>Collapsed</Visibility>
//							</ei:ChangePropertyAction.Value>
//						</ei:ChangePropertyAction>
//					</i:EventTrigger>
//				</i:Interaction.Triggers>
//			</TextBlock>
//		</StackPanel>
//	</Grid>
//</UserControl>
namespace System
namespace System.ComponentModel
Multiple items
type MainViewModel =
  interface INotifyPropertyChanged
  new : unit -> MainViewModel
  member TriggerPropertyChanged : name:string -> unit
  member HiLabel : string
  member MyName : string
  member MyName : string with set

Full name: HelloAppViewModel.MainViewModel

--------------------
new : unit -> MainViewModel
val mutable myname : string
val event : Event<PropertyChangedEventHandler,PropertyChangedEventArgs>
Multiple items
module Event

from Microsoft.FSharp.Control

--------------------
type Event<'T> =
  new : unit -> Event<'T>
  member Trigger : arg:'T -> unit
  member Publish : IEvent<'T>

Full name: Microsoft.FSharp.Control.Event<_>

--------------------
type Event<'Delegate,'Args (requires delegate and 'Delegate :> Delegate)> =
  new : unit -> Event<'Delegate,'Args>
  member Trigger : sender:obj * args:'Args -> unit
  member Publish : IEvent<'Delegate,'Args>

Full name: Microsoft.FSharp.Control.Event<_,_>

--------------------
new : unit -> Event<'T>

--------------------
new : unit -> Event<'Delegate,'Args>
type INotifyPropertyChanged =
  event PropertyChanged : PropertyChangedEventHandler

Full name: System.ComponentModel.INotifyPropertyChanged
Multiple items
type CLIEventAttribute =
  inherit Attribute
  new : unit -> CLIEventAttribute

Full name: Microsoft.FSharp.Core.CLIEventAttribute

--------------------
new : unit -> CLIEventAttribute
val x : MainViewModel
override MainViewModel.PropertyChanged : IEvent<PropertyChangedEventHandler,PropertyChangedEventArgs>

Full name: HelloAppViewModel.MainViewModel.PropertyChanged
property Event.Publish: IEvent<PropertyChangedEventHandler,PropertyChangedEventArgs>
member MainViewModel.TriggerPropertyChanged : name:string -> unit

Full name: HelloAppViewModel.MainViewModel.TriggerPropertyChanged
val name : string
member Event.Trigger : sender:obj * args:'Args -> unit
Multiple items
type PropertyChangedEventArgs =
  inherit EventArgs
  new : propertyName:string -> PropertyChangedEventArgs
  member PropertyName : string

Full name: System.ComponentModel.PropertyChangedEventArgs

--------------------
PropertyChangedEventArgs(propertyName: string) : unit
member MainViewModel.MyName : string with set

Full name: HelloAppViewModel.MainViewModel.MyName
val set : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
val t : string
member MainViewModel.TriggerPropertyChanged : name:string -> unit
member MainViewModel.HiLabel : string

Full name: HelloAppViewModel.MainViewModel.HiLabel
property MainViewModel.MyName: string
Raw view Test code New version

More information

Link:http://fssnip.net/5l
Posted:13 years ago
Author:Tuomas Hietanen
Tags: silverlight , mvvm , viewmodel , xaml , inotifypropertychanged