如何在视图模型上使用DelegateCommand?

斯科特·尼姆罗德

是否有任何示例说明如何在用F#编写的视图模型上调用DelegateCommand?

我已经找到了一个DelegateCommand执行下面的代码在这里

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)

但是,对于F#还是陌生的,我不确定是否应该使用此实现,或者是否应该使用其他方法。

这是我确定如何执行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

我的视图模型如下:

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 @>)

我有以下基本视图模型:

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

更新:

我已将MVVM项目模板中为F#定义的RelayCommand修改为以下内容:

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)

然后,我如下更新了我的视图模型:

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))

但是,我不确定如何在Submit(DelegateCommand)上调用Execute函数

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

我知道这很简单,但是老实说我不知道​​如何做到这一点。

有什么建议么?

马克·西曼

Submit实现更改为此:

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

并这样称呼它:

viewModel.Submit.Execute() |> ignore

重要的更改是该Submit方法的返回类型现在ICommandDelegateCommand这是由于使用了upcast运算符:>

在F#中,所有接口都是显式实现的这意味着,尽管DelegateCommand实现了ICommand,但ICommand在声明(或推断为)为的对象上看不见的方法DelegateCommandICommand另一方面,当声明(或推断)该值为类型时,仅的成员ICommand可用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Django模型:如何在我的视图中获取模型对象

如何在Go中定义视图模型

如何在多个元素上使用相同的ng模型

使用MVVM,如何在低级服务和视图模型之间建立通信线路?

如何在MugenMvvm中获取与视图模型相关的视图

如何在MVC中的视图模型和服务中使用基类?

Rails:在Rails中如何在无表模型上使用模型的Attribute API

如何在Gamm mgcv模型上使用反向链接功能

如何在单个视图中使用两个模型?

如何在页面之间共享视图模型?

如何在Rails上使用ruby设置模型Twitter风格

我如何在敲出js的视图模型中使用多个视图

如何在另一个视图模型中使用一个模型属性?

在WPF MVVM上单击按钮,如何在命令对视图模型的引用之前或之后让我的视图执行某些操作?

如何在视图中显示参考模型?

如何在视图中获取模型类型

如何在Django的一页上具有2个模型/视图/模板?

如何在LINQ上正确使用模型映射器?

使用视图模型时,如何在mvc中实现pagedlist?

如何在CompositeCollection中使用视图模型的属性?

如何到达我的视图模型上的mediaFile并在其内容页面上使用它?

如何在视图之外获取视图模型

如何在 WPF 视图模型中使用关系表

如何在 Xamarin 中将数据从视图绑定到视图模型?

如何在另一个页面/视图模型上使用在一个视图模型中创建的数据?

如何在 ASP.NET 中使用视图模型?

如何在片段中使用共享视图模型

如何在BottomSheetDialog上使用视图绑定

如何让 Prism 的 DelegateCommand 观察子视图模型的属性?