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.

Copy Source
Copy Link
Tools:
 1: 
 2: 
 3: //MainViewModel.fs
 4: #light
 5: //Expression Blend support: wrap to namespace, not module
 6: namespace HelloAppViewModel
 7: 
 8: open System
 9: open System.ComponentModel
10: 
11: type MainViewModel() =
12: 
13:     let mutable myname = ""
14:     
15:     let event = new Event<_,_>()
16:     interface INotifyPropertyChanged with
17:         [<CLIEvent>]
18:         member x.PropertyChanged = event.Publish
19:     
20:     member x.TriggerPropertyChanged(name)=
21:         event.Trigger(x, new PropertyChangedEventArgs(name))
22:     
23:     member x.MyName 
24:         with get() = myname
25:         and set t = 
26:                 myname <- t
27:                 x.TriggerPropertyChanged "MyName"
28:                 x.TriggerPropertyChanged "HiLabel"
29: 
30:     member x.HiLabel = "Hello " + x.MyName + "!"
31: 
32: ////---------------------------------------------------------------------------------------
33: ////View codebehind: MainPage.xaml.cs
34: //
35: //using System.Windows.Controls;
36: //namespace HelloApp
37: //{
38: //	public partial class MainPage : UserControl
39: //	{
40: //		public MainPage()
41: //		{
42: //			  // Required to initialize variables
43: //			  InitializeComponent();
44: //            this.DataContext = new HelloAppViewModel.MainViewModel();
45: //		}
46: //	}
47: //}
48: 
49: ////---------------------------------------------------------------------------------------
50: ////View xaml: Mainpage.xaml
51: //<UserControl
52: //	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
53: //	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
54: //	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
55: //	xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
56: //	x:Class="HelloApp.MainPage"
57: //	Width="640" Height="480">
58: //
59: //	<Grid x:Name="LayoutRoot" Background="White" d:DataContext="{d:DesignData /SampleData/MainViewModelSampleData.xaml}">
60: //		<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Width="400">
61: //			<TextBlock TextWrapping="Wrap" Text="Input your name:"/>
62: //			<StackPanel Orientation="Horizontal">
63: //				<TextBox x:Name="MyNameTextbox" TextWrapping="Wrap" Text="{Binding MyName, Mode=TwoWay}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200">
64: //					<i:Interaction.Triggers>
65: //						<i:EventTrigger EventName="TextChanged">
66: //							<ei:ChangePropertyAction TargetName="HelloLabel" PropertyName="Visibility"/>
67: //						</i:EventTrigger>
68: //					</i:Interaction.Triggers>
69: //				</TextBox>
70: //				<Button Content="Hi!" HorizontalAlignment="Right" VerticalAlignment="Top"/>
71: //			</StackPanel>
72: //			<TextBlock x:Name="HelloLabel" TextWrapping="Wrap" Text="{Binding HiLabel}">
73: //				<i:Interaction.Triggers>
74: //					<i:EventTrigger>
75: //						<ei:ChangePropertyAction PropertyName="Visibility">
76: //							<ei:ChangePropertyAction.Value>
77: //								<Visibility>Collapsed</Visibility>
78: //							</ei:ChangePropertyAction.Value>
79: //						</ei:ChangePropertyAction>
80: //					</i:EventTrigger>
81: //				</i:Interaction.Triggers>
82: //			</TextBlock>
83: //		</StackPanel>
84: //	</Grid>
85: //</UserControl>
86: 
87: 
namespace HelloAppViewModel
namespace System
namespace System.ComponentModel
type MainViewModel =
  class
    interface INotifyPropertyChanged
    new : unit -> MainViewModel
    member TriggerPropertyChanged : name:string -> unit
    member HiLabel : string
    member MyName : string
    member MyName : string with set
  end

Full name: HelloAppViewModel.MainViewModel

  type: MainViewModel
  implements: INotifyPropertyChanged
val mutable myname : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val event : Event<PropertyChangedEventHandler,PropertyChangedEventArgs>
Multiple items
module Event

from Microsoft.FSharp.Control

--------------------

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

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

--------------------

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

Full name: Microsoft.FSharp.Control.Event<_>
Multiple items
type INotifyPropertyChanged =

Full name: System.ComponentModel.INotifyPropertyChanged

--------------------

INotifyPropertyChanged
type CLIEventAttribute =
  class
    inherit Attribute
    new : unit -> CLIEventAttribute
  end

Full name: Microsoft.FSharp.Core.CLIEventAttribute

  type: CLIEventAttribute
  implements: Runtime.InteropServices._Attribute
  inherits: Attribute
Multiple items
val x : MainViewModel

  type: MainViewModel
  implements: INotifyPropertyChanged


--------------------

val x : MainViewModel

  type: MainViewModel
  implements: INotifyPropertyChanged


--------------------

val x : MainViewModel

  type: MainViewModel
  implements: INotifyPropertyChanged
property Event.Publish: IEvent<PropertyChangedEventHandler,PropertyChangedEventArgs>
val x : MainViewModel

  type: MainViewModel
  implements: INotifyPropertyChanged
member MainViewModel.TriggerPropertyChanged : name:string -> unit

Full name: HelloAppViewModel.MainViewModel.TriggerPropertyChanged
val name : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
member Event.Trigger : sender:obj * args:'Args -> unit
type PropertyChangedEventArgs =
  class
    inherit System.EventArgs
    new : string -> System.ComponentModel.PropertyChangedEventArgs
    member PropertyName : string
  end

Full name: System.ComponentModel.PropertyChangedEventArgs

  type: PropertyChangedEventArgs
  inherits: EventArgs
Multiple items
val x : MainViewModel

  type: MainViewModel
  implements: INotifyPropertyChanged


--------------------

val x : MainViewModel

  type: MainViewModel
  implements: INotifyPropertyChanged
property MainViewModel.MyName: string
val set : seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
val t : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
member MainViewModel.TriggerPropertyChanged : name:string -> unit
member MainViewModel.HiLabel : string

Full name: HelloAppViewModel.MainViewModel.HiLabel

More information

Link: http://fssnip.net/5l
Posted: 3 years ago
Author: Tuomas Hietanen (website)
Tags: Silverlight, MVVM, ViewModel, XAML, INotifyPropertyChanged