2016-01-09 14 views
8

Czy istnieje przykład, jak wywołać DelegateCommand na viewmodel napisane w F #?Jak używać DelegateCommand na viewmodel?

znalazłem następujący kod do implementacji DelegateCommand here:

type DelegateCommand<a>(execute : 'a -> unit, ?canExecute : 'a -> bool) = 
    let event = Event<_,_>() 
    interface ICommand with 
    member this.CanExecute(param : obj) = 
     if canExecute.IsSome then 
     canExecute.Value(param :> 'a) 
     else true 
    member this.Execute (param : obj) = 
     execute(param :> 'a) 

jednak nie jest nowy w F #, nie jestem pewien, czy powinienem używać tej implementacji lub jeśli istnieje jakaś inna podejście powinienem być dźwignia.

Oto test, który chciałbym wykonać kiedyś dowiedzieć się, jak wykonać DelegateCommand:

module CreateProfileViewModel.Tests 

open FsUnit 
open NUnit.Framework 
open CreateProfile.UILogic 

[<Test>] 
let ``create profile``() = 

    // Setup 
    let viewModel = ViewModel() 
    viewModel.FirstName <- "Scott" 
    viewModel.LastName <- "Nimrod" 

    // Test 
    viewModel.Submit.Execute(); 

    // Verify 
    let expected = false // TODO - implement some state-change 
    expected |> should equal true 

Moje ViewModel jest następujący:

module CreateProfile 

open Core.UILogic 

type ViewModel() = 
    inherit ViewModelBase() 
    let mutable firstName = "" 
    let mutable lastName = "" 

    member this.FirstName 
     with get() = firstName 
     and set(value) = 
      firstName <- value 
      base.NotifyPropertyChanged(<@ this.FirstName @>) 

    member this.LastName 
     with get() = lastName 
     and set(value) = 
      lastName <- value 
      base.NotifyPropertyChanged(<@ this.LastName @>) 

mam następujący model bazy danych:

module Core.UILogic 

open System.ComponentModel 
open Microsoft.FSharp.Quotations.Patterns 

type ViewModelBase() = 
    let propertyChanged = 
     Event<PropertyChangedEventHandler,PropertyChangedEventArgs>() 

    let getPropertyName = function 
     | PropertyGet(_,pi,_) -> pi.Name 
     | _ -> invalidOp "Expecting property getter expression" 

    interface INotifyPropertyChanged with 
     [<CLIEvent>] 
     member this.PropertyChanged = propertyChanged.Publish 

    member private this.NotifyPropertyChanged propertyName = 
     propertyChanged.Trigger(this,PropertyChangedEventArgs(propertyName)) 

    member this.NotifyPropertyChanged quotation = 
     quotation |> getPropertyName |> this.NotifyPropertyChanged 

Aktualizacja:

Mam zmodyfikowano RelayCommand zdefiniowany w szablonie projektu MVVM dla F # na następujące kwestie:

module UILogic.Interaction 

open System 
open System.Windows 
open System.Windows.Input 
open System.ComponentModel 

type DelegateCommand (action:(obj -> unit), canExecute:(obj -> bool)) = 
    let event = new DelegateEvent<EventHandler>() 
    interface ICommand with 
     [<CLIEvent>] 
     member this.CanExecuteChanged = event.Publish 
     member this.CanExecute arg = canExecute(arg) 
     member this.Execute arg = action(arg) 

I wtedy aktualizowany mój ViewModel następująco:

module CreateProfile.UILogic 

open UILogic.State 
open UILogic.Interaction 

type ViewModel() = 
    inherit ViewModelBase() 

    let mutable _firstName = "" 
    let mutable _lastName = "" 
    let mutable _submitted = false 

    member this.FirstName 
     with get() = _firstName 
     and set(value) = 
      _firstName <- value 
      base.NotifyPropertyChanged(<@ this.FirstName @>) 

    member this.LastName 
     with get() = _lastName 
     and set(value) = 
      _lastName <- value 
      base.NotifyPropertyChanged(<@ this.LastName @>) 

    member this.IsSubmitted 
     with get() = _submitted 
     and set(value) = _submitted <- value 

    member this.Submit = 
     new DelegateCommand ((fun _ -> this.IsSubmitted <- true), (fun _ -> true)) 

Jednak nie jestem pewien, jak wywołać funkcję wykonaj na Zatwierdź (DelegateCommand):

module CreateProfileViewModel.Tests 

open FsUnit 
open NUnit.Framework 
open UILogic.State 
open CreateProfile.UILogic 

[<Test>] 
let ``create profile``() = 

    // Setup 
    let viewModel = ViewModel() 
    viewModel.FirstName <- "Scott" 
    viewModel.LastName <- "Nimrod" 

    // Test 
    ignore viewModel.Submit.Execute(); // How to invoke execute? 

    // Verify 
    viewModel.IsSubmitted |> should equal true 

Wiem, że to banalne, ale szczerze mówiąc nie mam pojęcia jak to zrobić.

Wszelkie sugestie?

+0

Dlaczego nie używasz gotowych rozwiązań? - FSharp.ViewModule –

+0

@ Foggy Finder: Naprawdę chcę zrozumieć i polecić F # w mojej praktyce programistycznej. Guy Coder stanowił doskonałe odniesienie. W tej chwili studiuję ich implementację, aby móc nią manipulować, gdy próbuję wchłonąć ten język i jego mechanikę. –

+0

Jakie jest twoje pytanie? Gdzie masz problemy? –

Odpowiedz

3

Zmień realizację Submit do tego:

member this.Submit = 
    DelegateCommand ((fun _ -> this.IsSubmitted <- true), (fun _ -> true)) :> ICommand 

i nazwać tak:

viewModel.Submit.Execute() |> ignore 

Ważną zmianą jest to, że Submit METHOD typ zwracany jest teraz ICommand zamiast DelegateCommand. Jest to spowodowane wykorzystaniem operatora upcast :>.

W języku F # wszystkie interfejsy są jawnie zaimplementowane. Oznacza to, że chociaż DelegateCommand implementuje ICommand, metody ICommand nie są widoczne dla obiektów zadeklarowanych (lub wywnioskowanych) jako DelegateCommand. Kiedy wartość jest zadeklarowana (lub wywnioskowana), aby być typu ICommand, z drugiej strony, dostępne są tylko elementy z ICommand.

2

Ponieważ nie użyłem MVC lub MVVM z F # nie mogę podać konkretnego przykładu kodu.

Dla

jednak nie jest nowy w F #, nie jestem pewien, czy powinienem używać tej implementacji czy istnieje jakiś inny podejście powinno być dźwigni.

Jeśli używasz programu Visual Studio, który również ma community edition, który można pobrać za darmo, istnieją szablony dla MVC i MVVM.

Aby uzyskać dostęp do szablonów z VS za pomocą menu.

File -> New -> Project

enter image description here

Rozwiń Online
Rozwiń Szablony
Rozwiń programu Visual F #

w prawym górnym rogu na "Szukaj szablonów online" wprowadź termin taki jak MVC lub MVVM

enter image description here

Wybierz jeden lub sprawdź kilka.

Uwaga: niektóre z szablonów mają kilka lat, a F # i Windows rozwijały się po drodze, więc starałem się unikać starszych. Również autorów popularnych można zazwyczaj znaleźć w Internecie, a niektórzy są tutaj, więc zadaj pytania dotyczące szczegółów.

Możesz również wyświetlić inne szablony, kontrolki i rozszerzenia na VS pod numerem Visual Studio Gallery za pomocą przeglądarki internetowej.

Ostrzeżenie: Niektóre z rozszerzeń spowodują problemy po zainstalowaniu, szczególnie te starsze lub mniej popularne, więc należy zachować ostrożność i nie instalować ich na maszynie produkcyjnej, zanim nie zostaną najpierw przetestowane na innym komputerze.

+0

Dzięki Guy Coder. Twój wkład/wskazówki częściowo odpowiedział na moje pytanie. Zaktualizowałem stan mojego pytania dotyczącego wywoływania funkcji, która po prostu nie wydaje się być odsłonięta. –

Powiązane problemy