以下ViewModel在F#中的外观如何?
namespace MVVMExample
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
RaisePropertyChanged("FirstName");
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
RaisePropertyChanged("LastName");
}
}
public string GetFullName()
{
return string.Format("{0} {1}", FirstName, LastName);
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
注:
我是F#的新手,确实想了解如何简化C#中的代码。
答案 0 :(得分:3)
我更喜欢使用基类ViewModel
继承并公开使用引号的接口,因此我不需要手工提供字符串属性名称(这对代码重构不友好)。
请注意,根据问题的接受答案:Is it possible to use CallerMemberNameAttribute in f# F#不支持[<CallerMemberName>]
属性,因此我使用引号来执行此操作。
如果您在C#中定义基类ViewModel
类并从F#中继承该类,您仍然可以获得[<CallerMemberName>]
的好处。出于这个答案的目的,我将向您展示一个纯粹的F#解决方案。
type ViewModel () =
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
然后从中获取您的具体ViewModel
。
type NimrodViewModel() =
inherit ViewModel()
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 @>)
member this.GetFullName() =
sprintf "%s %s" (this.FirstName) (this.LastName)
答案 1 :(得分:1)
使用FSharp.Desktop.UI,它看起来像这样:
if (c >= 0 && c <= 9)
ViewModel的实例将由[<AbstractClass>]
type ViewModel() =
inherit Model()
abstract FirstName: string with get, set
abstract LastName: string with get, set
[<DerivedProperty>]
member this.FullName = sprintf "%s %s" this.FirstName this.LastName
创建。
通过使let model: MyViewModel = ViewModel.Create()
属性并使用FullName
属性进行装饰,任何绑定到它的控件都会在其所依赖的任何属性发生更改时自动获得更改通知。
我知道您没有要求使用库的示例,但我希望展示在使用正确的社区库时F#的简洁程度。