It is worth noting that MVVM and code are not best friends.
#, , Window code-behind (.. ). - , MVVM. XAML MVVM Commands.
A - , .
, FsXaml ( XAML), .
, XAML, .
UserDialog.xaml
<Button x:Name="butt" ... >
UserDialog.xaml.fs
namespace Views
open FsXaml
type UserDialogBase = XAML<"UserDialog.xaml">
type UserDialog() as dlg =
inherit UserDialogBase()
do dlg.butt.Click.Add( fun _ -> dlg.DialogResult <- System.Nullable(true) )
ViewModel, . :
B - MVVM DialogCloser.
(Solution Explorer)
DialogCloser.fs
namespace Views
open System.Windows
type DialogCloser() =
static let dialogResultProperty =
DependencyProperty.RegisterAttached("DialogResult",
typeof<bool>, typeof<DialogCloser>,
new PropertyMetadata(DialogCloser.DialogResultChanged))
static member SetDialogResult (a:DependencyObject) (value:string) =
a.SetValue(dialogResultProperty, value)
static member DialogResultChanged
(a:DependencyObject) (e:DependencyPropertyChangedEventArgs) =
match a with
| :? Window as window
-> window.DialogResult <- System.Nullable (e.NewValue :?> bool)
| _ -> failwith "Not a Window"
, WpfApp ( XAML), DialogCloser :
UserDialog.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:Views;assembly=WpfApp"
xmlns:fsxaml="http://github.com/fsprojects/FsXaml"
views:DialogCloser.DialogResult="{Binding DialogResult}"
>
...
</Window>
UserDialog ViewModel Command , dialogResult true.
member __.OkCommand = __.Factory.CommandSync(fun () ->
if not <| isValidEmail(email.Value) then
System.Windows.MessageBox.Show ("...") |> ignore
else
// do stuff (e.g. saving data)
...
// Terminator
dialogResult.Value <- true
)
if/else .
, MainViewModel :
UserDialog.xaml.fs
namespace Views
open FsXaml
type UserDialog = XAML<"UserDialog.xaml">
module UserDialogHandling =
let getResult() =
let win = UserDialog()
match win.ShowDialog() with
| nullable when nullable.HasValue
-> nullable.Value
| _ -> false
, "-" ( UserDialog).