[<CLIMutable>] for discriminated unions (adding setter to properties when compiled
[<CLIMutable>] for discriminated unions (adding setter to properties when compiled
I am playing with MVVM pattern in Silverlight, using F# for the viewmodel code in a separate library project.
As far as I can see, the properties of the cases have only get methods, and no setters. I think it might be useful to add [<CLIMutable>] also for discriminated unions, this way I can let the fields be changed through the GUI easily.
Below is an example of what I am doing. Btw. I am using Fody.PropertyChanged to implement the INotifyPropertyChanged interface for me :)
These are the types in the VM code:
[<ImplementPropertyChangedAttribute>]
[<CLIMutableAttribute>]
type Record =
{
Field1 : string
Field2 : int
}
[<ImplementPropertyChangedAttribute>]
type Union =
| CaseA of string
| CaseB of int
| CaseC of Record
[<ImplementPropertyChangedAttribute>]
type ViewModel() =
member val Model = CaseB 5
with get, setAnd this is how I bind them in XAML:
For cases A and B -> two way binding doesn't work here, I suppose because there is no setter
<TextBox Text="{Binding Model.Item, Mode=TwoWay}"></TextBox>
For case C where there is a record -> here the binding works as expected
<TextBox Text="{Binding Model.Item.Field1, Mode=TwoWay}"></TextBox>
Is there maybe a better way to do this?
I found a solution for this - I created a Fody addin which creates setters for fields of union cases through IL weaving after the assembly has been compiled. You can find more information about IL weaving at https-://github.-com/Fody/Fody/.
My solution can be found at https-://github.-com/ndamjan/FSharpHelper.Fody. What this addin also does is that it removes the need to put CLIMutableAttribute on record types, the addin creates a default contructor and adds setters to otherwise readonly properties.
Feel free to contact me if you need more information.