diff --git a/src/Fabulous.XamarinForms/CollectionBuilderExtensions.fs b/src/Fabulous.XamarinForms/CollectionBuilderExtensions.fs index 764c18b..67c4894 100644 --- a/src/Fabulous.XamarinForms/CollectionBuilderExtensions.fs +++ b/src/Fabulous.XamarinForms/CollectionBuilderExtensions.fs @@ -86,6 +86,13 @@ type CollectionBuilderExtensions = ) : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } + [] + static member inline Yield<'msg, 'marker, 'itemType when 'marker :> ICell and 'itemType :> IMenuItem> + ( + _: AttributeCollectionBuilder<'msg, 'marker, IMenuItem>, + x: WidgetBuilder<'msg, 'itemType> + ) : Content<'msg> = + { Widgets = MutStackArray1.One(x.Compile()) } [] static member inline Yield<'msg, 'marker, 'itemType when 'itemType :> IPage> diff --git a/src/Fabulous.XamarinForms/Views/Cells/_Cell.fs b/src/Fabulous.XamarinForms/Views/Cells/_Cell.fs index 059b095..948034a 100644 --- a/src/Fabulous.XamarinForms/Views/Cells/_Cell.fs +++ b/src/Fabulous.XamarinForms/Views/Cells/_Cell.fs @@ -30,6 +30,9 @@ module Cell = let Tapped = Attributes.defineEventNoArg "Cell_Tapped" (fun target -> (target :?> Cell).Tapped) + let ContextActions = + Attributes.defineListWidgetCollection "Cell_ContextActions" (fun target -> (target :?> Cell).ContextActions) + [] type CellModifiers = @@ -56,3 +59,7 @@ type CellModifiers = [] static member inline onTapped(this: WidgetBuilder<'msg, #ICell>, onTapped: 'msg) = this.AddScalar(Cell.Tapped.WithValue(MsgValue onTapped)) + + [] + static member inline contextActions<'msg, 'marker when 'marker :> ICell>(this: WidgetBuilder<'msg, 'marker>) = + WidgetHelpers.buildAttributeCollection<'msg, 'marker, IMenuItem> Cell.ContextActions this diff --git a/src/Fabulous.XamarinForms/Views/Pages/_MultiPageOfPage.fs b/src/Fabulous.XamarinForms/Views/Pages/_MultiPageOfPage.fs index e84c62b..d95e8ad 100644 --- a/src/Fabulous.XamarinForms/Views/Pages/_MultiPageOfPage.fs +++ b/src/Fabulous.XamarinForms/Views/Pages/_MultiPageOfPage.fs @@ -1,6 +1,8 @@ namespace Fabulous.XamarinForms +open System open Fabulous +open Fabulous.ScalarAttributeDefinitions open Xamarin.Forms open System.Runtime.CompilerServices @@ -11,9 +13,57 @@ module MultiPageOfPage = let Children = Attributes.defineListWidgetCollection "MultiPageOfPage" (fun target -> (target :?> MultiPage).Children) + [] let CurrentPageChanged = Attributes.defineEventNoArg "MultiPageOfPage_CurrentPageChanged" (fun target -> (target :?> MultiPage).CurrentPageChanged) + let CurrentPageWithEvent = + let name = "MultiPageOfPage_CurrentPageWithEvent" + + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun oldValueOpt (newValueOpt: ValueEventData voption) node -> + let target = node.Target :?> MultiPage + let event = target.CurrentPageChanged + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the event + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> event.RemoveHandler(handler) + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> target.CurrentPage <- target.Children.[0] + + | ValueSome curr -> + // Clean up the old event handler if any + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> event.RemoveHandler(handler) + + // Set the new value + target.CurrentPage <- target.Children.[curr.Value] + + // Set the new event handler + let handler = + EventHandler(fun sender args -> + let multiPage = sender :?> MultiPage + let currentPageIndex = multiPage.Children.IndexOf(multiPage.CurrentPage) + let (MsgValue r) = curr.Event currentPageIndex + Dispatcher.dispatch node r) + + node.SetHandler(name, ValueSome handler) + event.AddHandler(handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name }: SimpleScalarAttributeDefinition> + + [] type MultiPageOfPageModifiers = /// Raised when the CurrentPage property changes. @@ -21,3 +71,7 @@ type MultiPageOfPageModifiers = [] static member inline onCurrentPageChanged(this: WidgetBuilder<'msg, #IMultiPageOfPage>, onCurrentPageChanged: 'msg) = this.AddScalar(MultiPageOfPage.CurrentPageChanged.WithValue(MsgValue onCurrentPageChanged)) + + [] + static member inline currentPage(this: WidgetBuilder<'msg, #IMultiPageOfPage>, currentPage: int, onCurrentPageChanged: int -> 'msg) = + this.AddScalar(MultiPageOfPage.CurrentPageWithEvent.WithValue(ValueEventData.create currentPage onCurrentPageChanged))