benttranberg / exploreelmishwpf Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
I am using Form2 of ExploreElmishWpf
The Form2 tab consists of two textboxes and a submit button. The submit button will not be used. The updated textbox values are intended to be automatically saved into an xml file. For the sake of simplicity, deserialization and further usage of saved values are omitted.
Notice where the myUpdate
function in the update
function is placed (Form2.fs) and notice the binding in the Text
property (Form2.xaml):
Form2.fs
namespace ExploreElmishWpf.Models
open System
open System.IO;
open Newtonsoft.Json //Install-Package Newtonsoft.Json -Version 13.0.1
open System.Runtime.Serialization
type TestRecord =
{
input1: string
input2: string
}
module Serialisation =
//simplified serialisation without FileInfo checks, try-with blocks and without Option.ofObj
let serialize record =
let filepath = Path.GetFullPath("json.xml")
let xmlSerializer = new DataContractSerializer(typedefof<string>)
use stream = File.Create(filepath)
xmlSerializer.WriteObject(stream, JsonConvert.SerializeObject(record))
module Form2 =
open System
open Elmish
open Elmish.WPF
open Serialisation
type Model =
{
Input1: string
Input2: string
}
type Msg =
| Text1Input of string
| Text2Input of string
| Submit // not used
let init =
{
Input1 = "Value in txtBox1"
Input2 = "Value in txtBox2"
}
let myUpdate m =
let myCopyOfTestRecord = //this is what should be saved into json.xml
{
input1 = m.Input1
input2 = m.Input2
}
serialize myCopyOfTestRecord
m
let update msg m =
match msg with
| Text1Input s -> { myUpdate m with Input1 = s }
| Text2Input s -> { myUpdate m with Input2 = s }
| Submit -> m // not used
let bindings () : Binding<Model, Msg> list =
[
"Input1" |> Binding.twoWay ((fun m -> m.Input1), (fun newVal -> newVal |> Text1Input))
"Input2" |> Binding.twoWay ((fun m -> m.Input2), (fun newVal -> newVal |> Text2Input))
"Submit" |> Binding.cmd Submit // not used
]
Form2.xaml
<UserControl x:Class="ExploreElmishWpf.Form2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ExploreElmishWpf"
mc:Ignorable="d"
Padding="10">
<StackPanel Width="300">
<TextBlock Text="Form 2" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,5" />
<TextBox Text="{Binding Input1, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="0,5,0,5">
</TextBox>
<TextBox Text="{Binding Input2, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="0,5,0,5">
</TextBox>
<Button Command="{Binding Submit}" Content="Submit" />
</StackPanel>
</UserControl>
Run the app and type "Hello" and leave "Value in txtBox2" and look at the content of json.xaml in the Debug (or Release respectively) folder. "Hell" and "Value in txtBox2" are saved. Type "Hello" into both textboxes and look at json.xaml - "Hello" and "Hell" are saved.
The last character is not saved. I think it is because the myUpdate
function is fired BEFORE the UpdateSourceTrigger
property is triggered.
My solution consists of creating a separate Update
message initiated by a TextChanged
event. Like in the following code.
Form2.fs
namespace ExploreElmishWpf.Models
open System
open System.IO;
open Newtonsoft.Json //Install-Package Newtonsoft.Json -Version 13.0.1
open System.Runtime.Serialization
type TestRecord =
{
input1: string
input2: string
}
module Serialisation =
//simplified serialisation without FiloInfo checks, try-with blocks and without Option.ofObj
let serialize record =
let filepath = Path.GetFullPath("json.xml")
let xmlSerializer = new DataContractSerializer(typedefof<string>)
use stream = File.Create(filepath)
xmlSerializer.WriteObject(stream, JsonConvert.SerializeObject(record))
module Form2 =
open System
open Elmish
open Elmish.WPF
open Serialisation
type Model =
{
Input1: string
Input2: string
}
type Msg =
| Text1Input of string
| Text2Input of string
| Submit // not used
| Update
let init =
{
Input1 = "Value in txtBox1"
Input2 = "Value in txtBox2"
}
let myUpdate m =
let myCopyOfTestRecord = //this is what should be saved into json.xml
{
input1 = m.Input1
input2 = m.Input2
}
serialize myCopyOfTestRecord
m
let update msg m =
match msg with
| Text1Input s -> { m with Input1 = s } //compare with { myUpdate m with Input1 = s }
| Text2Input s -> { m with Input2 = s } //compare with { myUpdate m with Input1 = s }
| Submit -> m // not used
| Update -> myUpdate m
let bindings () : Binding<Model, Msg> list =
[
"Input1" |> Binding.twoWay ((fun m -> m.Input1), (fun newVal -> newVal |> Text1Input))
"Input2" |> Binding.twoWay ((fun m -> m.Input2), (fun newVal -> newVal |> Text2Input))
"Update" |> Binding.cmd Update
"Submit" |> Binding.cmd Submit // not used
]
Form2.xaml
<UserControl x:Class="ExploreElmishWpf.Form2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:ExploreElmishWpf"
mc:Ignorable="d"
Padding="10">
<!--
Install-Package Microsoft.Xaml.Behaviors.Wpf -Version 1.1.39
-->
<StackPanel Width="300">
<TextBlock Text="Form 2" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,5" />
<TextBox Text="{Binding Input1, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="0,5,0,5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction PassEventArgsToCommand="False" Command="{Binding Update}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBox Text="{Binding Input2, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="0,5,0,5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction PassEventArgsToCommand="False" Command="{Binding Update}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Button Command="{Binding Submit}" Content="Submit" />
</StackPanel>
</UserControl>
If you know of a better solution, thanx for sharing it here :-) .
I have a WPF Tab Control (in C#) where each tab uses a different UserControl with a different ViewModel as datacontext. In the C# application, only the Tab being viewed has the active window. As I'm a newbie to Elmish (and F#), an example of how to switch between tabs with Elmish would be most appreciated.
Thanks. AW
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.