Vì vậy, đây là một số đoạn mã ướt nhất mà tôi từng viết. Nhưng nó rất hữu ích, gây phiền nhiễu. Lý do cho tất cả sự lặp lại là vì tôi muốn giữ giao diện thông thạo. Nếu tôi tăng cường các lớp cơ sở (trong đó sẽ xảy ra là View
trong trường hợp này), nó sẽ chỉ trả lại một thể hiện của View
, trong đó sẽ ngăn cản tôi làm điều gì đó nhưLàm cách nào để tôi có thể TẮT mã F # này? (Giao diện thông thạo)
let label = theme.CreateLabel().WithMargin(new Thickness(5.0)).WithText("Hello")
vì tài sản Label.Text
không được thực hiện bởi lớp cơ sở View
.
Vì vậy, đây là giao diện thông thạo của tôi. Chuẩn bị. Nó xấu xí và lặp đi lặp lại. Nhưng nó cũng hoạt động và thuận tiện để sử dụng.
Tôi đã bỏ lỡ một cách rõ ràng để DỪNG?
module ViewExtensions =
let private withTwoWayBinding<'TElement, 'TProperty, 'TViewModel, 'TView when 'TView :> IViewFor<'TViewModel>>(viewModel: 'TViewModel, view: 'TView, viewModelProperty: Expr<'TViewModel -> 'TProperty>, viewProperty: Expr<'TView -> 'TProperty>) (element: 'TElement) =
view.Bind(viewModel, ExpressionConversion.toLinq viewModelProperty, ExpressionConversion.toLinq viewProperty) |> ignore
element
let private withHorizontalOptions<'TElement when 'TElement :> View> options (element: 'TElement) =
element.HorizontalOptions <- options
element
let private withVerticalOptions<'TElement when 'TElement :> View> options (element: 'TElement) =
element.VerticalOptions <- options
element
let private withAlignment<'TElement when 'TElement :> View> horizontalOptions verticalOptions (control: 'TElement) =
control |> withHorizontalOptions horizontalOptions |> withVerticalOptions verticalOptions
let private withMargin<'TElement when 'TElement :> View> margin (element: 'TElement) =
element.Margin <- margin
element
let private withActions<'TElement> (actions: ('TElement -> unit)[]) (element: 'TElement) =
for action in actions do action(element)
element
type Xamarin.Forms.Entry with
member this.WithHorizontalOptions(options) = withHorizontalOptions options this
member this.WithVerticalOptions(options) = withHorizontalOptions options this
member this.WithAlignment(horizontalOptions, verticalOptions) = withAlignment horizontalOptions verticalOptions this
member this.WithTwoWayBinding(viewModel, view, viewModelProperty, viewProperty) = withTwoWayBinding(viewModel, view, viewModelProperty, viewProperty) this
member this.WithMargin(margin) = withMargin margin this
member this.With(actions) = withActions actions this
member this.With(action: Entry -> unit) = this.With([|action|])
type Xamarin.Forms.Grid with
member this.WithHorizontalOptions(options) = withHorizontalOptions options this
member this.WithVerticalOptions(options) = withHorizontalOptions options this
member this.WithAlignment(horizontalOptions, verticalOptions) = withAlignment horizontalOptions verticalOptions this
member this.WithMargin(margin) = withMargin margin this
member this.With(actions) = withActions actions this
member this.With(action: Grid -> unit) = this.With([|action|])
type Xamarin.Forms.StackLayout with
member this.WithHorizontalOptions(options) = withHorizontalOptions options this
member this.WithVerticalOptions(options) = withHorizontalOptions options this
member this.WithAlignment(horizontalOptions, verticalOptions) = withAlignment horizontalOptions verticalOptions this
member this.WithMargin(margin) = withMargin margin this
member this.With(actions) = withActions actions this
member this.With(action: StackLayout -> unit) = this.With([|action|])
type Xamarin.Forms.Button with
member this.WithHorizontalOptions(options) = withHorizontalOptions options this
member this.WithVerticalOptions(options) = withHorizontalOptions options this
member this.WithAlignment(horizontalOptions, verticalOptions) = withAlignment horizontalOptions verticalOptions this
member this.WithMargin(margin) = withMargin margin this
member this.WithText(text) = this.Text <- text; this
member this.With(actions) = withActions actions this
member this.With(action: Button -> unit) = this.With([|action|])
type Xamarin.Forms.Switch with
member this.WithHorizontalOptions(options) = withHorizontalOptions options this
member this.WithVerticalOptions(options) = withHorizontalOptions options this
member this.WithAlignment(horizontalOptions, verticalOptions) = withAlignment horizontalOptions verticalOptions this
member this.WithTwoWayBinding(viewModel, view, viewModelProperty, viewProperty) = withTwoWayBinding(viewModel, view, viewModelProperty, viewProperty) this
member this.WithMargin(margin) = withMargin margin this
member this.With(actions) = withActions actions this
member this.With(action: Switch -> unit) = this.With([|action|])
type Xamarin.Forms.Label with
member this.WithHorizontalOptions(options) = withHorizontalOptions options this
member this.WithVerticalOptions(options) = withHorizontalOptions options this
member this.WithAlignment(horizontalOptions, verticalOptions) = withAlignment horizontalOptions verticalOptions this
member this.WithMargin(margin) = withMargin margin this
member this.WithText(text) = this.Text <- text; this
member this.With(actions) = withActions actions this
member this.With(action: Label -> unit) = this.With([|action|])
CẬP NHẬT
Vì vậy, nhờ sự giúp đỡ của bạn, câu trả lời là có, tôi nhớ da diết cái gì đó rõ ràng. Như TheQuickBrownFox giải thích, nếu tôi thay đổi giao diện thông thạo một cái gì đó có dạng
let label = theme.CreateLabel() |> withMargin(new Thickness(5.0)) |> withContent("Hello")
sau đó con quái vật mà bạn nhìn thấy ở trên có thể được thay thế hoàn toàn bởi
module ViewExtensions =
let withTwoWayBinding<'TElement, 'TProperty, 'TViewModel, 'TView when 'TView :> IViewFor<'TViewModel>>(viewModel: 'TViewModel, view: 'TView, viewModelProperty: Expr<'TViewModel -> 'TProperty>, viewProperty: Expr<'TView -> 'TProperty>) (element: 'TElement) =
view.Bind(viewModel, ExpressionConversion.toLinq viewModelProperty, ExpressionConversion.toLinq viewProperty) |> ignore
element
let withHorizontalOptions options (element: #View) = element.HorizontalOptions <- options; element
let withVerticalOptions options (element: #View) = element.VerticalOptions <- options; element
let withAlignment horizontalOptions verticalOptions element = element |> withHorizontalOptions horizontalOptions |> withVerticalOptions verticalOptions
let withMargin margin (element: #View) = element.Margin <- margin; element
let withCaption text (element: #Button) = element.Text <- text; element
let withText text (element: #Entry) = element.Text <- text; element
let withContent text (element: #Label) = element.Text <- text; element
let withSetUpActions<'TElement> (actions: ('TElement -> unit)[]) (element: 'TElement) = (for action in actions do action(element)); element
let withSetUpAction<'TElement> (action: 'TElement -> unit) = withSetUpActions([|action|])
xóa Mã này là rất hài lòng thực sự.
bạn không thể làm postfix ứng dụng (aka "ống về phía trước") thay vì các phương pháp mở rộng? Bằng cách đó bạn có thể làm cho các hàm chung với các ràng buộc. –
Tôi phải thừa nhận, tôi đã không hoàn toàn chắc chắn những gì bạn có nghĩa là cho đến khi tôi đọc câu trả lời của TheQuickBrownFox. Nó làm cho cảm giác hoàn hảo ngay bây giờ. Và nó hoạt động rất độc đáo. Đang chờ cập nhật. –