{"id":24320917,"url":"https://github.com/fmglib/fmglib.mauimarkup","last_synced_at":"2025-09-27T04:32:02.187Z","repository":{"id":218184270,"uuid":"745817812","full_name":"FmgLib/FmgLib.MauiMarkup","owner":"FmgLib","description":"About FmgLib.MauiMarkup with C# Markup classes and fluent helper methods","archived":false,"fork":false,"pushed_at":"2024-04-13T19:20:21.000Z","size":910,"stargazers_count":8,"open_issues_count":2,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2024-04-14T09:51:57.384Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FmgLib.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-01-20T08:25:49.000Z","updated_at":"2024-08-19T20:00:30.993Z","dependencies_parsed_at":"2024-02-11T16:26:15.839Z","dependency_job_id":"d2184b05-25fd-486e-9334-617057719686","html_url":"https://github.com/FmgLib/FmgLib.MauiMarkup","commit_stats":null,"previous_names":["fmglib/fmglib.mauimarkup"],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FmgLib%2FFmgLib.MauiMarkup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FmgLib%2FFmgLib.MauiMarkup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FmgLib%2FFmgLib.MauiMarkup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FmgLib%2FFmgLib.MauiMarkup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FmgLib","download_url":"https://codeload.github.com/FmgLib/FmgLib.MauiMarkup/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234390656,"owners_count":18824642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-17T16:19:31.526Z","updated_at":"2025-09-27T04:32:02.180Z","avatar_url":"https://github.com/FmgLib.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# FmgLib.MauiMarkup\n\n### Free .NET Libraries by FmgLib.MauiMakrup\n\n| NuGet Package | Link | Repo Info |\n|--------------|------|-------|\n| `FmgLib.MauiMarkup` | [![NuGet](https://img.shields.io/nuget/v/FmgLib.MauiMarkup?includePreReleases=true)](https://www.nuget.org/packages/FmgLib.MauiMarkup/) ![NuGet Downloads](https://img.shields.io/nuget/dt/FmgLib.MauiMarkup.svg) | [![GitHub Stars](https://img.shields.io/github/stars/FmgLib/FmgLib.MauiMarkup?style=flat-square\u0026color=blue)](https://github.com/FmgLib/FmgLib.MauiMarkup/stargazers) [![GitHub Forks](https://img.shields.io/github/forks/FmgLib/FmgLib.MauiMarkup?style=flat-square\u0026color=green)](https://github.com/FmgLib/FmgLib.MauiMarkup/forks) [![GitHub last-commit](https://img.shields.io/github/last-commit/FmgLib/FmgLib.MauiMarkup?style=flat-square)](https://github.com/FmgLib/FmgLib.MauiMarkup/commits) |\n| `FmgLib.MauiMarkup.Template` | [![NuGet](https://img.shields.io/nuget/v/FmgLib.MauiMarkup.Template?includePreReleases=true)](https://www.nuget.org/packages/FmgLib.MauiMarkup.Template/) ![NuGet Downloads](https://img.shields.io/nuget/dt/FmgLib.MauiMarkup.Template.svg) | - |\n\n\u003cbr\u003e\n\nFmgLib.MauiMarkup is a specialized library crafted for .NET MAUI. This library allows you to code directly in C# without the necessity of employing XAML language. It provides developers with a straightforward and flexible approach to building user interfaces using C# code. With FmgLib.MauiMarkup, you can now develop application interfaces in a code-focused manner, avoiding the complexities of dealing with XAML files. This library accelerates your development process while enabling you to write more readable and manageable code.\n\nFmgLib.MauiMarkup provides extension methods for all properties provided for a View on the XAML side.\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eGetting Started\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n### Creating a new FmgLib.MauiMarkup project from CLI\n\nFmgLib provides a project template to start a new project with FmgLib.MauiMarkup.\n\n**Install latest templates from NuGet:**\n```bash\ndotnet new install FmgLib.MauiMarkup.Template\n```\n\n**Create a new project:**\n\n```bash\ndotnet new fmglib-mauimarkup-app -o my-new-project\n```\n\n\u003cbr\u003e\n\n### Existing Projects\n\nInstall the [FmgLib.MauiMarkup](https://www.nuget.org/packages/FmgLib.MauiMarkup/) NuGet package to your MAUI application.\n```bash\ndotnet add package FmgLib.MauiMarkup\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eXAML to FmgLib.MauiMarkup(C#)\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nIf we were to write XAML code for the Image class, it would look like this:\n\n```xaml\n\u003cImage\n    Source=\"dotnet_bot.png\"\n    HeightRequest=\"100\"\n    WidthRequest=\"150\"\n    Grid.Row=\"0\"\n    Grid.Column=\"1\"\n    Grid.RowSpan=\"2\"\n    Opacity=\".8\" /\u003e\n```\n\nThe C# equivalent with the help of FmgLib.MauiMarkup would be as follows:\n\n```csharp\nnew Image()\n.Source(\"dotnet_bot.png\")\n.Row(0)\n.Column(1)\n.RowSpan(2)\n.SizeRequest(150,100)\n.Opacity(.8)\n```\n\nSimilarly, we can see this for other Views. Let's write a few sample codes as an example:\n\n```csharp\nnew Label()\n.Text(\"fmglib.mauimarkup\")\n.FontSize(12)\n.Row(1)\n.TextColor(Colors.Green)\n.FontAttributes(FontAttributes.Bold)\n.Margin(new Thickness(5,3,0,5))\n```\n\n```csharp\nthis\n.BackgroundImageSource(\"background.jpg\")\n.Content(\n    new StackLayout()\n    .Center()\n    .Children(\n        new ActivityIndicator()\n        .IsRunning(true)\n        .HeightRequest(70)\n        .WidthRequest(70)\n        .Center()\n        .InvokeOnElement(ai =\u003e ai.Loaded += CheckLogin(sender, e))\n    )\n);\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eHow to assign object references\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nThere are two main ways to assign objects in `FmgLib.MauiMarkup`: \n\n- using the `Assign` method,\n\nThe first example uses the `Assign` method to assign a label object to a variable named label. This is done using the following code:\n\n```csharp\nnew Label().Assign(out var label);\nnew Entry().Assign(out var entry);\n```\nOr\n\n```csharp\nButton btnOk;\n\nnew Button()\n.Assign(out btnOk);\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eAttached properties\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nAttached properties are properties that are defined on a type but are intended to be used with instances of other types. In `FmgLib.MauiMarkup`, attached properties are matched with attached property fluent methods, allowing you to set their values in a more readable and fluent manner.\n\nFor example, if you want to set the `AbsoluteLayout.LayoutBounds` attached property on a Border object, you would create an instance of Border and then use the `AbsoluteLayoutBounds` fluent method to set its value, like this:\n\n```csharp\nnew Border().AbsoluteLayoutBounds(new Rect(100, 100, 200, 200));\n```\n\nThis would set the `AbsoluteLayout.LayoutBounds` attached property to the specified rectangle value on the `Border` object.\n\n## Attached properties list\n\n | Maui bağlı özelliği | FmgLib.MauiMarkup metodu |\n |-|-|\n |`FlyoutBase.ContextFlyout`|`ContextFlyout()`|\n |`Grid.Column`|`Column()`|\n |`Grid.Row`|`Row()`|\n |`Grid.ColumnSpan`|`ColumnSpan()`|\n |`Grid.RowSpan`|`RowSpan()`|\n |`Grid.ColumnSpan`+`Grid.RowSpan`|`Span(column, row)`|\n |`VisualStateManager.VisualStateGroups`|`VisualStateGroups()`|\n |`RadioButtonGroup.GroupName`|`RadioButtonGroupGroupName()`|\n |`RadioButtonGroup.SelectedValue`|`RadioButtonGroupSelectedValue()`|\n |`AbsoluteLayout.LayoutFlags`|`AbsoluteLayoutFlags()`|\n |`AbsoluteLayout.LayoutBounds`|`AbsoluteLayoutBounds()`|\n |`BindableLayout.EmptyView`|`BindableLayoutEmptyView()`|\n |`BindableLayout.EmptyViewTemplate`|`BindableLayoutEmptyViewTemplate()`| \n |`BindableLayout.ItemsSource`|`BindableLayoutItemsSource()`|\n |`BindableLayout.ItemTemplate`|`BindableLayoutItemTemplate()`|\n |`BindableLayout.TemplateSelector`|`BindableItemTemplateSelector()`|\n |`Shell.PresentationMode`|`ShellPresentationMode()`|\n |`Shell.BackgroundColor`|`ShellBackgroundColor()`|\n |`Shell.ForegroundColor`|`ShellForegroundColor()`|\n |`Shell.TitleColor`|`ShellTitleColor()`|\n |`Shell.DisabledColor`|`ShellDisabledColor()`|\n |`Shell.UnselectedColor`|`ShellUnselectedColor()`|\n |`Shell.NavBarHasShadow`|`ShellNavBarHasShadow()`|\n |`Shell.NavBarIsVisible`|`ShellNavBarIsVisible()`|\n |`Shell.TitleView`|`ShellTitleView()`|\n |`Shell.TabBarBackgroundColor`|`ShellTabBarBackgroundColor()`|\n |`Shell.TabBarForegroundColor`|`ShellTabBarForegroundColor()`|\n |`Shell.TabBarTitleColor`|`ShellTabBarTitleColor()`|\n |`Shell.TabBarDisabledColor`|`ShellTabBarDisabledColor()`|\n |`Shell.TabBarUnselectedColor`|`ShellTabBarUnselectedColor()`|\n |`Shell.TabBarIsVisible`|`ShellTabBarIsVisible()`|\n |`Shell.FlyoutBackdrop`|`ShellFlyoutBackdrop()`|\n |`Shell.FlyoutBehavior`|`ShellFlyoutBehavior()`|\n |`Shell.FlyoutHeight`|`ShellFlyoutHeight()`|\n |`Shell.FlyoutWidth`|`ShellFlyoutWidth()`|\n |`Shell.FlyoutItemIsVisible`|`ShellFlyoutItemIsVisible()`|\n |`Shell.BackButtonBehavior`|`ShellBackButtonBehavior()`|\n |`Shell.ItemTemplate`|`ShellItemTemplate()`|\n |`Shell.MenuItemTemplate`|`ShellMenuItemTemplate()`|\n |`Shell.SearchHandler`|`ShellSearchHandler()`|\n |`NavigationPage.HasNavigationBar`|`NavigationPageHasNavigationBar()`|\n |`NavigationPage.BackButtonTitle`|`NavigationPageBackButtonTitle()`|\n |`NavigationPage.HasBackButton`|`NavigationPageHasBackButton()`|\n |`NavigationPage.IconColor`|`NavigationPageIconColor()`|\n |`NavigationPage.TitleIconImageSource`|`NavigationPageTitleIconImageSource()`|\n |`NavigationPage.TitleView`|`NavigationPageTitleView()`|\n |`SemanticProperties.Hint`|`SemanticHint()`|\n |`SemanticProperties.Description`|`SemanticDescription()`|\n |`SemanticProperties.HeadingLevel`|`SemanticHeadingLevel()`|\n |`AutomationProperties.ExcludedWithChildren`|`AutomationExcludedWithChildren()`|\n |`AutomationProperties.IsInAccessibleTree`|`AutomationIsInAccessibleTree()`|\n |`AutomationProperties.Name`|`AutomationName()`|\n |`AutomationProperties.HelpText`|`AutomationHelpText()`|\n |`AutomationProperties.LabeledBy`|`AutomationLabeledBy()`|\n |`ToolTipProperties.Text`|`ToolTipPropertiesText()`|\n\n\u003c/details\u003e\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eBehaviors\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nIn `FmgLib.MauiMarkup`, you can add functionality to user interface controls using behaviors. Behaviors allow you to add functionality to controls without having to subclass them.\n\nYou can add a behavior to a control by using the `Behaviors` method and passing in an instance of the behavior class. For example:\n\n```csharp\nnew Entry().Text(\"Click Item\")\n  .Behaviors(new YourCustomBehaviors());\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eBinding Converters\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nThis code is an example of how to use binding converters in `FmgLib.MauiMarkup`. \n\nA `CollectionView` is defined and for each item in the `MyNumbers` list, a label is created with text equal to the value of the item. The `BackgroundColor` property of the label is bound to the item using the `Convert` method, which takes in a function that converts the value of the item (an integer) to a color. In this case, the function checks if the number is even or odd, and returns either `Colors.Green` or `Colors.Yellow` based on the result.\n\n```csharp\npublic class CustomPage : ContentPage\n{\n    public List\u003cint\u003e MyNumbers = new List\u003cint\u003e { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };\n\n    public CustomPage()\n    {\n\t    this\n\t    .Content(\n\t\t\tnew VerticalStackLayout()\n\t\t\tChildren(\n\t\t\t\tnew CollectionView()\n                .ItemsSource(MyNumbers)\n                .ItemTemplate(() =\u003e \n                    new Label()\n                        .FontSize(30)\n                        .Text(e =\u003e e.Path(\".\"))\n                        .TextColor(Colors.Gray)\n                        .BackgroundColor(e =\u003e e\n                            .Path(\".\")\n                            .Convert((int n) =\u003e n % 2 == 0 ? Colors.Green : Colors.Yellow)\n                        )\n                )\n\t\t\t)\n\t\t);\n    }\n}\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eEvent handlers\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nIn Maui, you can add functionality to user interface controls by handling events. For each `EventHandler` in a `FmgLib.MauiMarkup` class, a fluent helper method is generated to make it easier to attach an event handler to the control.\n\nFor example, in the case of the `Clicked` event handler in the `Button` class, two fluent methods are generated:\n\n- `OnClicked(Button sender)`\n- `OnClicked(object sender, EventArgs e)`\n\nHere's an example of how you can use the fluent helper method `OnClicked` to handle the `Clicked` event on a `Button` control:\n\n```csharp\nusing FmgLib.MauiMarkup;\n\npublic class ExamPage : ContentPage\n{\n    int count = 0;\n    public ExamPage()\n    {\n        this\n\t    .Content(\n\t\t\tnew VerticalStackLayout()\n\t\t\t.Children(\n\t            ...\n\t            new Button()\n\t\t\t\t.Text(\"Click me\")\n\t            .OnClicked(OnCounterClicked),\n\t            ...\n            )\n        );\n    }\n\n    private void OnCounterClicked(Button sender)\n    {\n        count++;\n        sender.Text = $\"Clicked {count} \";\n        sender.Text += count == 1 ? \"time\" : \"times\";\n    }\n}\n``` \nOr, you can use an inline function to handle the event:\n\n```csharp\nnew Button()\n\t.Text(\"Click me\")\n    .OnClicked(button =\u003e\n    {\n        count++;\n        button.Text = $\"Clicked {count} \";\n        button.Text += count == 1 ? \"time\" : \"times\";\n    })\n``` \n\nThis makes it easy to attach event handlers to controls in a concise and readable way.\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eGesture Recognizers\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nThe following gesture recognizers are available:\n\n- `TapGestureRecognizer`\n- `PanGestureRecognizer`\n- `PointerGestureRecognizer`\n\n### Tap Gesture Recognizer\n\nThe `TapGestureRecognizer` class is used to detect tap gestures on a view. You can specify the number of taps required using the `NumberOfTapsRequired` property.\n\nHere's an example of using the TapGestureRecognizer to detect a double-tap gesture on an image:\n\n```csharp\nnew StackLayout()\n.Children(\n    new Label()\n    .Text(\"Tap 2 times on the image\")\n    .Assign(out var label),\n    new Image()\n    .Source(\"dotnet_bot.png\")\n    .Assign(out var image)\n\t.SizeRequest(100,100)\n\t.GestureRecognizers(new GestureRecognizer[]\n        {\n            new TapGestureRecognizer()\n                .NumberOfTapsRequired(2)\n                .OnTapped((e, args) =\u003e\n                {\n                    label.Text = \"You tapped 2 times\";\n                })\n        })\n)\n```\n\n### Pan Gesture Recognizer\n\nThe `PanGestureRecognizer` class is used to detect pan gestures on a view. You can use the `OnPanUpdated` method to handle the pan gesture event and update the position of the view.\n\nHere's an example of using the `PanGestureRecognizer` to move an image on the screen:\n\n```csharp\npublic class PanGesturePage : ContentPage\n{\n    double x, y;\n\n    public PanGesturePage()\n    {\n        this\n        .Content(\n\t        new Grid()\n\t        .Children(\n\t            new Image()\n\t\t\t    .Source(\"dotnet_bot.png\")\n\t\t\t    .Assign(out var image)\n                .SizeRequest(100,100)\n                .GestureRecognizers(new GestureRecognizer[]\n                {\n                    new PanGestureRecognizer()\n                        .OnPanUpdated((e, args) =\u003e\n                        {\n                            switch (args.StatusType)\n                            {\n                                case GestureStatus.Running:\n                                    image.TranslationX = x + args.TotalX;\n                                    image.TranslationY = y + args.TotalY;\n                                    break;\n\n                                case GestureStatus.Completed:\n                                    x = image.TranslationX;\n                                    y = image.TranslationY;\n                                    break;\n                            }\n                        })\n                })\n            )\n        );\n    }\n}\n```\n\n### Pointer Gesture Recognizer\n\nThe `PointerGestureRecognizer` class is used to detect pointer events such as entering, exiting, and moving on a view. You can use the `OnPointerEntered`, `OnPointerExited`, and `OnPointerMoved` methods to handle these events and update the view accordingly.\n\nHere's an example of using the `PointerGestureRecognizer` to display the position of a pointer on an image:\n\n```csharp\npublic class PointerGesturePage : ContentPage\n{\n    public PointerGesturePage()\n    {\n        this\n        .Content(\n\t        new StackLayout()\n\t        .Center()\n\t        .Children(\n\t            new Label().Assign(out var label).FontSize(20),\n\t            new Label().Assign(out var enterExitLabel).FontSize(20).TextColor(Colors.Blue),\n\t            new Image()\n\t\t\t\t    .Source(\"dotnet_bot.png\")\n\t\t\t\t    .Assign(out var image)\n\t                .SizeRequest(300,300)\n\t                .GestureRecognizers(new GestureRecognizer[]\n\t                {\n\t                    new PointerGestureRecognizer()\n\t                        .OnPointerEntered((e, args) =\u003e\n\t                        {\n\t                            enterExitLabel.Text = \"Entered\";\n\t                        })\n\t                        .OnPointerExited((e, args) =\u003e\n\t                        {\n\t                            enterExitLabel.Text = \"Exited\";\n\t                        })\n\t                        .OnPointerMoved((e, args) =\u003e\n\t                        {\n\t                            var pos = args.GetPosition(relativeTo: image).Value;\n\t                            label.Text = $\"point: {pos.X}, {pos.Y}\";\n\t                        })\n\t                })\n\t          )  \n        };\n    }\n}\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eGradients\u003c/b\u003e\u003c/summary\u003e\n    \n\u003cbr\u003e\n\u003cbr\u003e\n`FmgLib.MauiMarkup` provides a way to create visual effects using gradient brushes in curly braces. There are two defined types of gradient brushes: \n\n- LinearGradientBrush \n- RadialGradientBrush.\n\n### Example\n\nHere is an example of a `Border` element with a `LinearGradientBrush` as its background. The gradient effect goes from the top-left corner to the bottom-right corner.\n\n```csharp\nnew Border()\n.Background(\n\tnew LinearGradientBrush()\n\t.StartPoint(new Point(0,0))\n\t.EndPoint(new Point(1,1))\n\t.GradientStops(\n\t\tnew List\u003cGradientStop\u003e(){\n\t\t\tnew GradientStop(Colors.Yellow, 0.0),\n\t\t    new GradientStop(Colors.Red, 0.25),\n\t\t    new GradientStop(Colors.Blue, 0.75),\n\t\t    new GradientStop(Colors.LimeGreen, 1.0)\n\t    }\n\t)\n)\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eGrid Definition\u003c/b\u003e\u003c/summary\u003e\n    \n\u003cbr\u003e\n\u003cbr\u003e\nThe `Grid` element allows you to create complex, multi-row and multi-column layout using Row and Column definitions. You can define the number and size of the rows and columns using the `RowDefinitions` and `ColumnDefinitions` methods, respectively.\n\nYou can set the position of a child element within the grid using the `Row()`, `Column()`, `ColumnSpan()`, and `RowSpan()` methods. These methods match the attached properties `Grid.Row`, `Grid.Column`, `Grid.ColumnSpan`, and `Grid.RowSpan`, respectively.\n\n### Row and column definition\n\nDefining the number and size of rows and columns is done using the `RowDefinitions` and `ColumnDefinitions` methods, respectively. These methods take a lambda function that defines the properties for the row or column.\n\nIn the following example, you're defining a `Grid` element with four rows and two columns:\n\n```csharp\nnew Grid()\n.RowDefinitions(e =\u003e e.Star(2).Star(0.5, count: 3)))\n.ColumnDefinitions(e =\u003e e.Absolute(100).Star())\n.Children(\n\t...\n)\n``` \n\nHere's what the code is doing:\n\nThe `RowDefinitions` method is defining four rows with different sizes. The first row takes up 2 stars, which means it will take up twice as much vertical space as any other row in the Grid. The second, third, and fourth rows each take up 0.5 stars. The count parameter is optional and specifies how many rows of the same size should be added to the Grid. In this case, it adds 3 rows of size 0.5 stars.\n\nThe `ColumnDefinitions` method is defining two columns. The first column is set to a fixed width of 100 pixels using the `Absolute` method, and the second column takes up the remaining space using the `Star` method.\n\n\n### Example\n\nHere is a full example of a grid definition:\n\n```csharp\nnew Grid()\n.RowDefinitions(e =\u003e e.Star(2).Star())\n.ColumnDefinitions(e =\u003e e.Absolute(200).Star()))\n.Children(\n    new BoxView().Color(Colors.Green),\n    new Label().Text(\"Column 0, Row 0\"),\n\n    new BoxView().Color(Colors.Blue).Column(1).Row(0),\n    new Label().Text(\"Column 1, Row 0\").Column(1).Row(0),\n\n    new BoxView().Color(Colors.Teal).Column(0).Row(1),\n    new Label().Text(\"Column 0, Row 1\").Column(0).Row(1),\n\n    new BoxView().Color(Colors.Purple).Column(1).Row(1),\n    new Label().Text(\"Column 1, Row 1\").Column(1).Row(1),\n)\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eITextAlignment interface extension methods\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\nIn `FmgLib.MauiMarkup`, all classes that implement the `ITextAlignment` interface get the following extension methods:\n\n - `TextCenterHorizontal`\n - `TextCenterVertical`\n - `TextCenter`\n - `TextLeft`\n - `TextRight`\n - `TextBottom`\n - `TextBottomLeft`\n - `TextBottomRight`\n - `TextTop`\n - `TextTopLeft`\n - `TextTopRight`\n - `TextTopCenter`\n - `TextBottomCenter`\n - `TextCenterLeft`\n - `TextCenterRight`\n - `AlignText`\n\n## Usage\n\nTo use the extension methods, create a `Label` object (or any object that implements `ITextAlignment`), and call the desired method:\n\n```csharp\nnew Label().TextCenter()\n```\n\nThis example centers the text both horizontally and vertically within the label's containing element.\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eLayout options\u003c/b\u003e\u003c/summary\u003e\n\nIn `FmgLib.MauiMarkup`, you can layout every view in their container using the following extension methods:\n\n - `CenterHorizontal`\n - `CenterVertical`\n - `Center`\n - `AlignLeft`\n - `AlignRight`\n - `AlignTop`\n - `AlignTopLeft`\n - `AlignTopRight`\n - `AlignBottom`\n - `AlignBottomLeft`\n - `AlignBottomRight`\n - `FillHorizontally`\n - `FillVertically`\n - `FillBothDirections`\n - `AlignTopCenter`\n - `AlignTopFill`\n - `AlignBottomCenter`\n - `AlignBottomFill`\n - `AlignCenterLeft`\n - `AlignCenterRight`\n - `AlignCenterFill`\n - `AlignFillLeft`\n - `AlignFillRight`\n - `AlignFillCenter`\n - `AlignLayout`\n\n## Usage\n\nTo use the layout options, create a container view , add the view you want to layout to the container, and call the desired method:\n\n```csharp\nnew StackLayout()\n.Children(\n    new Label().Text(\"Hello, World!\").Center()\n)\n```\n\nThis example centers a Label inside a `StackLayout` container. You can use the same method with other container views, and with any view that you want to lay out within its containing element.\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eMenus in FmgLib.MauiMarkup\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n### Context menu\n\nHere is an example of creating a context menu for an image. The context menu has options for copying and pasting, and also for changing the background color of a grid.\n\n```csharp\nnew Grid()\n.Assign(out var grid)\n.Children(\n    new Image()\n\t    .Source(\"dotnet_bot.png\")\n        .ContextFlyout(new MenuFlyout()\n\t\t\t{\n\t            new MenuFlyoutItem()\n\t            .Text(\"Copy\")\n\t\t\t\t.OnClicked(e =\u003e Console.WriteLine(\"Copy\")),\n\t            new MenuFlyoutItem()\n\t            .Text(\"Paste\")\n\t            .OnClicked(e =\u003e Console.WriteLine(\"Paste\")),\n\t            new MenuFlyoutSubItem()\n\t            {\n\t                new MenuFlyoutItem()\n\t                .Text(\"Blue\")\n\t                .OnClicked(e =\u003e grid.BackgroundColor = Colors.Blue),\n\t                new MenuFlyoutItem()\n\t                .Text(\"Red\")\n\t                .OnClicked(e =\u003e grid.BackgroundColor = Colors.Red),\n\t                new MenuFlyoutItem()\n\t                .Text(\"Black\")\n\t                .OnClicked(e =\u003e grid.BackgroundColor = Colors.Black)\n\t            }\n\t            .Text(\"Background color\")\n\t        }\n        )\n)\n```\n\n### Menu bar\n\nHere is an example of creating a menu bar for a `ContentPage`. The menu bar has three options: My Menu, Edit, and Theme.\n\n```csharp\npublic class MenuPage : ContentPage\n{\n    public MenuPage()\n    {\n        this.MenuBarItems(new MenuBarItem[]\n        {\n            new MenuBarItem()\n            {\n                new MenuFlyoutItem()\n\t\t            .Text(\"Exit\")\n                    .OnClicked(e =\u003e Application.Current.Quit()),\n            }\n            .Text(\"My Menu\"),\n            new MenuBarItem()\n            {\n                new MenuFlyoutItem()\n\t\t            .Text(\"Copy\")\n                    .OnClicked(e =\u003e Console.WriteLine(\"Copy\"))\n                    .KeyboardAccelerators(\n                        new KeyboardAccelerator()\n                        .Key(\"C\")\n                        .Modifiers(KeyboardAcceleratorModifiers.Ctrl)\n                    ),\n                new MenuFlyoutItem()\n\t\t            .Text(\"Paste\")\n                    .OnClicked(e =\u003e Console.WriteLine(\"Paste\"))\n                    .KeyboardAccelerators(\n                        new KeyboardAccelerator()\n                        .Key(\"V\")\n                        .Modifiers(KeyboardAcceleratorModifiers.Ctrl)\n                    ),\n            }\n            .Text(\"Edit\"),\n            new MenuBarItem()\n            {\n                new MenuFlyoutItem()\n\t                .Text(\"Blue\")\n                    .OnClicked(e =\u003e this.BackgroundColor = Colors.Blue),\n                ...\n            }\n            .Text(\"Theme\")\n        });\n\n        ...\n    }\n}\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eProperties and Fluent Methods\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n`FmgLib.MauiMarkup` provides a convenient way to set properties for UI elements by matching properties with fluent helper methods. This makes it easier and more readable to define the interface of your application.\n\nHere is an example of using fluent methods to set properties on a `Label`:\n\n```csharp\nnew Label()\n    .Text(\"This is a test\")\n    .Padding(20)\n    .FontSize(30)\n    .Center())\n```\n\n\n`FmgLib.MauiMarkup` also provides a way to set property values based on device idiom, platform, or app theme. Here is an example of setting the font size and text color of a `Label` based on the current device or theme:\n\n```csharp\nnew Label()\n\t.Text(\"Hello\")\n    .FontSize(e =\u003e e.OnDesktop(80).OnPhone(30).Default(50))\n    .TextColor(e =\u003e e.OnLight(Colors.Black).OnDark(Colors.Teal))\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eProperty Bindings\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n`FmgLib.MauiMarkup` provides a simple way to bind properties of an element to a source, so that when the source changes, the property changes as well. You can bind a property by using the fluent method e.g. `Text()`, `TextColor()` etc. and then using lambda call the method `Path()` to specify the property you want to bind to.\n\n\n```csharp\npublic class SimpleBindings : ContentPage\n{\n    public SimpleBindings()\n    {\n        this.Content(\n\t        new StackLayout()\n\t        Children(\n\t            new Slider()\n\t            .Assign(out var slider)\n                .Minimum(1)\n                .Maximum(20),\n\n\t            new Label()\n                .Text(e =\u003e e.Path(\"Value\").Source(slider).StringFormat(\"Slider value: {0}\"))\n                .FontSize(28)\n\t        )\n        );\n    }\n}\n``` \n\nIn this example, the text property of the label is bound to the `Value` property of a `Slider` element named `slider`. When the value of the slider changes, the text of the label will automatically update to reflect the new value.\n\nYou can also bind a property to an object that is not part of the visual tree. This is useful when you have a separate data source, such as a model or a view model, that you want to bind to a visual element.\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eProperty MultiBinding\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\nYou can easily use multibinding with FmgLib.MauiMarkup. You can add as many BindingBases as you want with the e.Bindings(...) method.\n\nExample usage is as follows:\n```csharp\npublic partial class MainPage : ContentPage, IFmgLibHotReload\n{\n    private readonly MainPageViewModel viewModel;\n    public MainPage()\n    {\n        viewModel = new MainPageViewModel();\n        this.InitializeHotReload();\n    }\n\n    public void Build()\n    {\n        this\n        .BindingContext(viewModel)\n        .Content(\n            new VerticalStackLayout()\n            .Spacing(20)\n            .Children(\n                new CheckBox()\n                .IsChecked(e =\u003e \n                    e.Bindings(\n                        new Binding().Path(\"Employee.IsOver16\"),\n                        new Binding().Path(\"Employee.HasPassedTest\"),\n                        new Binding().Path(\"Employee.IsSuspended\").Converter(new InverterConverter())\n                    )\n                    .Converter(new AllTrueMultiConverter())\n                    .FallbackValue(\"Is Error.\")\n                    .TargetNullValue(\"Is Null.\")\n                ),\n\n                new Label()\n                .Text(e =\u003e \n                    e.Bindings(\n                        new Binding().Path(\"Employee.Id\"),\n                        new Binding().Path(\"Employee.Name\"),\n                        new Binding().Path(\"Employee.IsSuspended\")\n                    )\n                    .StringFormat(\"{0} : {1} : {2}\")\n                    .FallbackValue(\"Is Error.\")\n                    .TargetNullValue(\"Is Null.\")\n                )\n            )\n        );\n    }\n}\n\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cb\u003eCompiled Bindings in Code\u003c/b\u003e\u003c/summary\u003e\n\n \u003cbr\u003e\n\nBindings written in code typically use string paths that are resolved at runtime with reflection, and the overhead of doing this varies from platform to platform. `FmgLib.MauiMarkup` introduces an additional Getter extension method that defines bindings using a Func argument instead of a string path:\n\n```csharp\n// in before\nnew Label().Text(e =\u003e e.Path(\"Text\"));\n\n// in now\nnew Label().Text(e =\u003e e.Getter(static (Entry entry) =\u003e entry.Text));\n```\n\nThis compiled binding approach provides the following benefits:\n  - Improved data binding performance by resolving binding expressions at compile-time rather than runtime.\n  - A better developer troubleshooting experience because invalid bindings are reported as build errors.\n  - Intellisense while editing.\n\nNot all methods can be used to define a compiled binding. The expression must be a simple property access expression. The following examples show valid and invalid binding expressions:\n\n```csharp\n// Valid: Property access\nstatic (PersonViewModel vm) =\u003e vm.Name;\nstatic (PersonViewModel vm) =\u003e vm.Address?.Street;\n\n// Valid: Array and indexer access\nstatic (PersonViewModel vm) =\u003e vm.PhoneNumbers[0];\nstatic (PersonViewModel vm) =\u003e vm.Config[\"Font\"];\n\n// Valid: Casts\nstatic (Label label) =\u003e (label.BindingContext as PersonViewModel).Name;\nstatic (Label label) =\u003e ((PersonViewModel)label.BindingContext).Name;\n\n// Invalid: Method calls\nstatic (PersonViewModel vm) =\u003e vm.GetAddress();\nstatic (PersonViewModel vm) =\u003e vm.Address?.ToString();\n\n// Invalid: Complex expressions\nstatic (PersonViewModel vm) =\u003e vm.Address?.Street + \" \" + vm.Address?.City;\nstatic (PersonViewModel vm) =\u003e $\"Name: {vm.Name}\";\n```\n\nYou can easily use multibinding with FmgLib.MauiMarkup. You can add as many BindingBases as you want with the e.Bindings(...) method. In addition, .NET MAUI 9 adds a BindingBase.Create method that sets the binding directly on the object with a Func, and returns the binding object instance:\n\n```csharp\npublic partial class MainPage : ContentPage, IFmgLibHotReload\n{\n    private readonly MainPageViewModel viewModel;\n    public MainPage()\n    {\n        viewModel = new MainPageViewModel();\n        this.InitializeHotReload();\n    }\n\n    public void Build()\n    {\n        this\n        .BindingContext(viewModel)\n        .Content(\n            new VerticalStackLayout()\n            .Spacing(20)\n            .Children(\n                new CheckBox()\n                .IsChecked(e =\u003e \n                    e.Bindings(\n\t\t\tBinding.Create(static (MainPageViewModel model) =\u003e model.IsOver16, source: RelativeBindingSource.Self),\n\t\t        Binding.Create(static (MainPageViewModel model) =\u003e model.HasPassedTest, source: RelativeBindingSource.Self),\n\t\t        Binding.Create(static (MainPageViewModel model) =\u003e model.IsSuspended, source: RelativeBindingSource.Self)\n                    )\n                    .Converter(new AllTrueMultiConverter())\n                    .FallbackValue(\"Is Error.\")\n                    .TargetNullValue(\"Is Null.\")\n                ),\n\n                new Label()\n                .Text(e =\u003e \n                    e.Bindings(\n\t\t\tBinding.Create(static (MainPageViewModel model) =\u003e model.Id, source: RelativeBindingSource.Self),\n\t\t        Binding.Create(static (MainPageViewModel model) =\u003e model.Name, source: RelativeBindingSource.Self),\n\t\t        Binding.Create(static (MainPageViewModel model) =\u003e model.IsSuspended, source: RelativeBindingSource.Self)\n                    )\n                    .StringFormat(\"{0} : {1} : {2}\")\n                    .FallbackValue(\"Is Error.\")\n                    .TargetNullValue(\"Is Null.\")\n                )\n            )\n        );\n    }\n}\n\n```\n \n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eShell Application\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nHere's an example of a simple shell-based application:\n\n```csharp\nusing FmgLib.MauiMarkup;\n\npublic partial class App : Application\n{\n    public App()\n    {\n        this.MainPage(\n\t        new Shell()\n\t        .ItemTemplate(() =\u003e new ShellItemTemplate())\n            .Resources(new ResourceDictionary().MergedDictionaries(AppStyles.Default))\n\t        .Items(\n\t\t\t\tnew FlyoutItem()\n\t\t\t\t.FlyoutDisplayOptions(FlyoutDisplayOptions.AsMultipleItems)\n\t\t\t\t.Items(\n\t                new Tab()\n\t                .Title(\"Main\")\n\t                .Items(\n\t                    new ShellContent()\n\t\t                .Title(\"Hello Page\")\n\t\t                .ContentTemplate(new HelloWorldPage()),\n\t                    new ShellContent()\n\t\t                .Title(\"ExamplePage\")\n\t\t                .ContentTemplate(new ExamplePage()),\n\t                ),\n\n\t                new ShellContent()\n\t                .Title(\"Grid\")\n\t                .ContentTemplate(new GridPage()),\n\t                ...\n\t            )\n\t\t\t)\n        );\n    }\n}\n```\n\nYou can customize the appearance of the `FlyoutItem` by defining a custom content view and setting the `ItemTemplate` property on the `Shell` element.\n\nHere's an example of defining the appearance of a `FlyoutItem`:\n\n```csharp\npublic class ShellItemTemplate : ContentView\n{\n    public ShellItemTemplate()\n    {\n        this\n        .Content(\n\t        new Grid()\n\t        .ColumnDefinitions(e =\u003e e.Star(0.2).Star(0.8))\n\t        .Children(\n\t            new Image()\n\t                .Source(e =\u003e e.Path(\"FlyoutIcon\"))\n\t                .Margin(5)\n\t                .HeightRequest(45),\n\n\t            new Label()\n\t                .GridColumn(1)\n\t                .Text(e =\u003e e.Path(\"Title\"))\n\t                .FontSize(20)\n\t                .FontAttributes(FontAttributes.Italic)\n\t                .CenterVertically()\n\t        )\n\t\t);\n    }\n}\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eApplication Styling\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\n`FmgLib.MauiMarkup` provides a way to define the styles of elements using the `Style\u003cT\u003e` class. Here's an example of how to define the style of a button: \n\n\n```csharp\nnew Style\u003cButton\u003e(e =\u003e e\n    .TextColor(e =\u003e e.OnLight(Colors.White).OnDark(AppColors.Primary))\n    .BackgroundColor(e =\u003e e.OnLight(AppColors.Primary).OnDark(Colors.White))\n    .FontFamily(\"OpenSansRegular\")\n    .FontSize(14)\n    .CornerRadius(8)\n    .Padding(new Thickness(14,10))\n    .MinimumHeightRequest(44)\n    .MinimumWidthRequest(44))\n```\n\nIn the example, the properties of a button are set using fluent extension methods.\n\nYou can also use different values depending on the app theme, device idiom, or platform:\n\nAdditionally, you can define visual states for elements:\n\n```csharp\nnew Style\u003cButton\u003e(e =\u003e e...)\n{\n    ...\n    new VisualState\u003cButton\u003e (VisualStateEnum.VisualElement.Normal, e =\u003e e\n        .TextColor(e =\u003e e.OnLight(Colors.White).OnDark(AppColors.Primary))\n        .BackgroundColor(e =\u003e e.OnLight(AppColors.Primary).OnDark(Colors.White))),\n\n    new VisualState\u003cButton\u003e (VisualStateEnum.VisualElement.Disabled, e =\u003e e\n        .TextColor(e =\u003e e.OnLight(AppColors.Gray950).OnDark(AppColors.Gray200))\n        .BackgroundColor(e =\u003e e.OnLight(AppColors.Gray200).OnDark(AppColors.Gray600))),\n},\n```\n\nYou can also use visual states to define animations:\n\n```csharp\nnew Style\u003cButton\u003e(e =\u003e e...)\n{\n    ...\n    \n    new VisualState\u003cButton\u003e(VisualStates.Button.Normal, e =\u003e e\n        .FontSize(33)\n        .TextColor(AppColors.Gray200))\n    {\n        async button =\u003e {\n            await button.RotateTo(0);   // create animation inside VisualState\n        }\n    },\n\n    new VisualState\u003cButton\u003e(VisualStates.Button.Disabled, e =\u003e e\n        .FontSize(20)\n        .TextColor(AppColors.Gray600))\n    {\n        async button =\u003e {\n            await button.RotateTo(180);\n        }\n    },\n}\n```\n\nFinally, all defined styles can be placed in a `ResourceDictionary`:\n\n```csharp\nnew ResourceDictionary\n{\n    ...\n\n    new Style\u003cButton\u003e(e =\u003e e\n        .TextColor(e =\u003e e.OnLight(Colors.White).OnDark(AppColors.Primary))\n        .BackgroundColor(e =\u003e e.OnLight(AppColors.Primary).OnDark(Colors.White))\n        .FontFamily(\"OpenSansRegular\")\n        .FontSize(14)\n        .CornerRadius(8)\n        .Padding(new Thickness(14,10))\n        .MinimumHeightRequest(44)\n        .MinimumWidthRequest(44))\n    {\n        new VisualState\u003cButton\u003e (VisualStateEnum.VisualElement.Normal, e =\u003e e\n            .TextColor(e =\u003e e.OnLight(Colors.White).OnDark(AppColors.Primary))\n            .BackgroundColor(e =\u003e e.OnLight(AppColors.Primary).OnDark(Colors.White))),\n\n        new VisualState\u003cButton\u003e (VisualStateEnum.VisualElement.Disabled, e =\u003e e\n            .TextColor(e =\u003e e.OnLight(AppColors.Gray950).OnDark(AppColors.Gray200))\n            .BackgroundColor(e =\u003e e.OnLight(AppColors.Gray200).OnDark(AppColors.Gray600)))\n    },      \n        \n    new Style\u003cFrame\u003e(e =\u003e e\n        .HasShadow(false)\n        .BorderColor(e =\u003e e.OnLight(AppColors.Gray200).OnDark(AppColors.Gray950))\n        .CornerRadius(8)),\n    ...\n};\n```\n\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eUser defined extension methods\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nIn `FmgLib:mauiMarkup`, you can create your own extension methods by defining a static method within a static class.\n\nHere's an example of extension methods that set a label font size:\n\n```csharp\npublic static T FontSize\u003cT\u003e(this T self,\n    double fontSize)\n    where T : Microsoft.Maui.Controls.Label\n{\n    self.SetValue(Microsoft.Maui.Controls.Label.FontSizeProperty, fontSize);\n    return self;\n}\n        \npublic static T FontSize\u003cT\u003e(this T self, Func\u003cPropertyContext\u003cdouble\u003e, IPropertyBuilder\u003cdouble\u003e\u003e configure)\n    where T : Microsoft.Maui.Controls.Label\n{\n    var context = new PropertyContext\u003cdouble\u003e(self, Microsoft.Maui.Controls.Label.FontSizeProperty);\n    configure(context).Build();\n    return self;\n}\n        \npublic static SettersContext\u003cT\u003e FontSize\u003cT\u003e(this SettersContext\u003cT\u003e self,\n    double fontSize)\n    where T : Microsoft.Maui.Controls.Label\n{\n    self.XamlSetters.Add(new Setter { Property = Microsoft.Maui.Controls.Label.FontSizeProperty, Value = fontSize });\n    return self;\n}\n        \npublic static SettersContext\u003cT\u003e FontSize\u003cT\u003e(this SettersContext\u003cT\u003e self, Func\u003cPropertySettersContext\u003cdouble\u003e, IPropertySettersBuilder\u003cdouble\u003e\u003e configure)\n    where T : Microsoft.Maui.Controls.Label\n{\n    var context = new PropertySettersContext\u003cdouble\u003e(self.XamlSetters, Microsoft.Maui.Controls.Label.FontSizeProperty);\n    configure(context).Build();\n    return self;\n}\n        \npublic static Task\u003cbool\u003e AnimateFontSizeTo\u003cT\u003e(this T self, double value, uint length = 250, Easing? easing = null)\n    where T : Microsoft.Maui.Controls.Label\n{\n    double fromValue = self.FontSize;\n    var transform = (double t) =\u003e Transformations.DoubleTransform(fromValue, value, t);\n    var callback = (double actValue) =\u003e { self.FontSize = actValue; };\n    return Transformations.AnimateAsync\u003cdouble\u003e(self, \"AnimateFontSizeTo\", transform, callback, length, easing);\n}\n```\n\nit allows you the following usage:\n\n```csharp\nnew Label().FontSize(28)\n```\n\nor:\n\n```csharp\nnew Label().FontSize(e =\u003e e.Path(\"MyFontSize\").Source(myModel))\nnew Label().FontSize(e =\u003e e.OnPhone(30).OnTablet(50).Default(40))\n```\n\nor use it in a style context:\n\n```csharp\nnew Style\u003cLabel\u003e(e =\u003e e\n    .FontSize(20)\n    .CenterVertically()\n    .CenterHorizontally())\n```\n\n\nor use in an animation context.\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eTriggers\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nTriggers allow you to set properties in response to certain conditions or events.\n\n### Property Triggers\n\nA property trigger sets a property in response to a change in the value of another property.\n\nHere is an example of using a property trigger to change the background color and text color of an `Entry` element when it gets focused:\n\n```csharp\nusing FmgLib:mauiMarkup;\n\npublic class PropertyTriggerPage : ContentPage\n{\n    public PropertyTriggerPage()\n    {\n\t    this\n        .Resources(\n\t        new ResourceDictionary\n\t        {\n\t            new Style\u003cEntry\u003e\n\t            {\n\t                Entry.BackgroundColorProperty.Set(Colors.Black),\n\t                Entry.TextColorProperty.Set(Colors.White),\n\n\t                new Trigger(typeof(Entry))\n\t                    .Property(Entry.IsFocusedProperty)\n\t                    .Value(true)\n\t                    .Setters(\n\t                        new Setters\u003cEntry\u003e(e =\u003e e\n\t                            .BackgroundColor(Colors.Yellow)\n\t                            .TextColor(Colors.Black))\n\t                    ),\n\t            }\n\t        }\n        )\n        .Content(\n\t\t\tnew StackLayout()\n\t\t\t.Children(\n\t\t\t\tnew Entry().Text(\"Enter name\"),\n\t            new Entry().Text(\"Enter password\"),\n\t            new Entry().Text(\"Enter address\")\n\t\t\t)\n\t\t);\n    }\n}\n```\n\n### Data Triggers\n\nA data trigger sets a property in response to a change in the value of a data source.\n\nHere is an example of using a data trigger to disable a button if the text length of an `Entry` element is zero:\n\n```csharp\nthis.Content(new StackLayout()\n\t.Children(\n\t    new Entry().Assign(out var entry).Text(\"Enter text...\"),\n\t    new Button()\n\t\t    .Text(\"Save\")\n\t        .Triggers(\n\t            new DataTrigger(typeof(Button))\n\t                .Binding(e =\u003e e.Path(\"Text.Length\").Source(entry))\n\t                .Value(0)\n\t                .Setters(new Setters\u003cEntry\u003e(e =\u003e e.IsEnabled(false)))\n\t        ),\n\t)\n)\n```\n\n### Event Triggers\n\nAn event trigger sets a property in response to an event.\n\nHere is an example of using an event trigger to validate the input of an `Entry` element as a number:\n\n```csharp\nthis\n.Content(new StackLayout()\n\t.Children(\n\t    new Entry()\n\t\t    .Assign(out var entry)\n\t\t    .Text(\"Enter text...\")\n\t        .Triggers(\n\t            new EventTrigger()\n\t                .Event(\"TextChanged\")\n\t                .Actions(new NumericValidationTriggerAction())\n\t        )\n\t)\n)\n```\n\nAnd here is the definition of the `NumericValidationTriggerAction` class:\n\n```csharp\npublic class NumericValidationTriggerAction : TriggerAction\u003cEntry\u003e\n{\n    protected override void Invoke(Entry entry)\n    {\n        double result;\n        bool isValid = Double.TryParse(entry.Text, out result);\n        entry.TextColor = isValid ? Colors.Black : Colors.Red;\n    }\n}\n```\n\nAnd here is the definition of the `NumericValidationTriggerAction` class:\n\n```csharp\npublic class NumericValidationTriggerAction : TriggerAction\u003cEntry\u003e\n{\n    protected override void Invoke(Entry entry)\n    {\n        double result;\n        bool isValid = Double.TryParse(entry.Text, out result);\n        entry.TextColor = isValid ? Colors.Black : Colors.Red;\n    }\n}\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003e.NET built-in Hot-Reload\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nAdditionally, the FmgLib.MauiMarkup library includes hot reload support to make the development process faster and more efficient.\n\nIf you want to enhance your page with fast reload, your page needs to implement the IFmgLibHotReload interface. Then, you should trigger the this.InitializeHotReload(); function within the constructor.\n\nAnd you can write your design code inside the `Build()` method to enhance it with fast reload.\n\nExample usage is as follows:\n\n```csharp\npublic partial class ExamplePage : ContentPage, IFmgLibHotReload\n{\n    public ExamplePage()\n    {\n        this.InitializeHotReload();\n    }\n    public void Build()\n    {\n        this\n        .Content(\n            new Label()\n            .Text(\"FmgLib.MauiMarkup\")\n            .CharacterSpacing(2)\n            .FontSize(30)\n            .FontAttributes(Italic)\n            .TextColor(Green)\n            .TextCenter()\n        );\n    }\n}\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eExtensions for 3rd Party Controls\u003c/b\u003e\u003c/summary\u003e\n    \n\u003cbr\u003e\n\u003cbr\u003e\nFmgLib.MauiMarkup library can also generate extension methods for controls from third-party libraries. To achieve this, you should utilize the `MauiMarkupAttribute` provided by FmgLib.MauiMarkup.\n\nSimply specify the control for which you want to create extension methods as `[MauiMarkup(typeof(YourControl))]`.\n\nThe constructor method of the `MauiMarkup()` attribute automatically generates extension methods for BindableProperties and Events found within the type provided as an argument. **You can provide a minimum of 1 type inside the constructor method, and there is no maximum limit.** **Multiple MauiMarkup attributes can be added to a single class.**\n\n**NOTE: Suppose that if a property inherited from base classes has been redefined with the `new` keyword in the class where you want to create a Fluent Method, the name of the new Fluent Method will be `PropertyName + New`.**\n\nFor example, since the **Background** property in the **SfAvatarView** class is redefined with `new` and is the same as the **Background** in **VisualElement**, to prevent errors, the Fluent Method name for the **Background** property of the **SfAvatarView** class will be `BackgroundNew`.\n\nLet's look at an example:\n\n```csharp\nusing FmgLib.MauiMarkup;\n\nnamespace GeneratedExam;\n\n[MauiMarkup(typeof(ZXing.Net.Maui.Controls.BarcodeGeneratorView))]\npublic class MyBarcodeGeneratorView { }\n\n[MauiMarkup(typeof(ZXing.Net.Maui.Controls.CameraView))]\npublic class MyCameraView { }\n\n\n[MauiMarkup(typeof(ZXing.Net.Maui.Controls.CameraBarcodeReaderView))]\npublic class MyCameraBarcodeReaderView { }\n\n[MauiMarkup(typeof(SkiaSharp.Extended.UI.Controls.SKLottieView))]\npublic class MySkLottieView { }\n\n```\n\nOr instead of dealing with it like this, it can be used like this:\n\n```csharp\nusing Microsoft.Extensions.Logging;\nusing FmgLib.MauiMarkup;\nusing SkiaSharp.Extended.UI.Controls;\nusing ZXing.Net.Maui.Controls;\nusing UraniumUI.Material.Controls;\nnamespace MauiApp1\n{\n    [MauiMarkup(typeof(CameraView))]\n    [MauiMarkup(typeof(SKLottieView), typeof(SKFileLottieImageSource), typeof(DataGrid))]\n    [MauiMarkup(typeof(SKConfettiView), typeof(BarcodeGeneratorView),typeof(InputField),typeof(EditorField),typeof(TextField))]\n    public static class MauiProgram\n    {\n        public static MauiApp CreateMauiApp()\n        {\n            var builder = MauiApp.CreateBuilder();\n            builder\n                .UseMauiApp\u003cApp\u003e()\n                .ConfigureFonts(fonts =\u003e\n                {\n                    fonts.AddFont(\"OpenSans-Regular.ttf\", \"OpenSansRegular\");\n                    fonts.AddFont(\"OpenSans-Semibold.ttf\", \"OpenSansSemibold\");\n                });\n\n#if DEBUG\n    \t\tbuilder.Logging.AddDebug();\n#endif\n            return builder.Build();\n        }\n    }\n}\n```\n\nCameraView class from ZXing.Net.Maui.Controls library:\n```csharp\n﻿using System;\nusing Microsoft.Maui.Controls;\nusing Microsoft.Maui.Graphics;\nusing System;\n\nnamespace ZXing.Net.Maui.Controls\n{\n\tpublic partial class CameraView : View, ICameraView\n\t{\n\t\tpublic event EventHandler\u003cCameraFrameBufferEventArgs\u003e FrameReady;\n\n\t\tvoid ICameraFrameAnalyzer.FrameReady(CameraFrameBufferEventArgs e)\n\t\t\t=\u003e FrameReady?.Invoke(this, e);\n\n\t\tpublic static readonly BindableProperty IsTorchOnProperty =\n\t\t\tBindableProperty.Create(nameof(IsTorchOn), typeof(bool), typeof(CameraView), defaultValue: true);\n\n\t\tpublic bool IsTorchOn\n\t\t{\n\t\t\tget =\u003e (bool)GetValue(IsTorchOnProperty);\n\t\t\tset =\u003e SetValue(IsTorchOnProperty, value);\n\t\t}\n\n\t\tpublic static readonly BindableProperty CameraLocationProperty =\n\t\t\tBindableProperty.Create(nameof(CameraLocation), typeof(CameraLocation), typeof(CameraView), defaultValue: CameraLocation.Rear);\n\n\t\tpublic CameraLocation CameraLocation\n\t\t{\n\t\t\tget =\u003e (CameraLocation)GetValue(CameraLocationProperty);\n\t\t\tset =\u003e SetValue(CameraLocationProperty, value);\n\t\t}\n\n\t\tpublic void AutoFocus()\n\t\t\t=\u003e StrongHandler?.Invoke(nameof(AutoFocus), null);\n\n\t\tpublic void Focus(Point point)\n\t\t\t=\u003e StrongHandler?.Invoke(nameof(Focus), point);\n\n\t\tCameraViewHandler StrongHandler \n\t\t\t=\u003e Handler as CameraViewHandler;\n\t}\n}\n```\n\n\nThe CameraViewExtension class created using the MauiMarkup attribute will be as follows:\n\n```csharp\n//\n// \u003cauto-generated-fmglib-mauimarkup-generator /\u003e\n//\n\n\nnamespace FmgLib.MauiMarkup;\n\npublic static partial class CameraViewExtension\n{\n        public static T CameraLocation\u003cT\u003e(this T self,\n            ZXing.Net.Maui.CameraLocation cameraLocation)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            self.SetValue(ZXing.Net.Maui.Controls.CameraView.CameraLocationProperty, cameraLocation);\n            return self;\n        }\n        \n        public static T CameraLocation\u003cT\u003e(this T self, Func\u003cPropertyContext\u003cZXing.Net.Maui.CameraLocation\u003e, IPropertyBuilder\u003cZXing.Net.Maui.CameraLocation\u003e\u003e configure)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            var context = new PropertyContext\u003cZXing.Net.Maui.CameraLocation\u003e(self, ZXing.Net.Maui.Controls.CameraView.CameraLocationProperty);\n            configure(context).Build();\n            return self;\n        }\n        \n        public static SettersContext\u003cT\u003e CameraLocation\u003cT\u003e(this SettersContext\u003cT\u003e self,\n            ZXing.Net.Maui.CameraLocation cameraLocation)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            self.XamlSetters.Add(new Setter { Property = ZXing.Net.Maui.Controls.CameraView.CameraLocationProperty, Value = cameraLocation });\n            return self;\n        }\n        \n        public static SettersContext\u003cT\u003e CameraLocation\u003cT\u003e(this SettersContext\u003cT\u003e self, Func\u003cPropertySettersContext\u003cZXing.Net.Maui.CameraLocation\u003e, IPropertySettersBuilder\u003cZXing.Net.Maui.CameraLocation\u003e\u003e configure)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            var context = new PropertySettersContext\u003cZXing.Net.Maui.CameraLocation\u003e(self.XamlSetters, ZXing.Net.Maui.Controls.CameraView.CameraLocationProperty);\n            configure(context).Build();\n            return self;\n        }\n        \n        public static T IsTorchOn\u003cT\u003e(this T self,\n            bool isTorchOn)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            self.SetValue(ZXing.Net.Maui.Controls.CameraView.IsTorchOnProperty, isTorchOn);\n            return self;\n        }\n        \n        public static T IsTorchOn\u003cT\u003e(this T self, Func\u003cPropertyContext\u003cbool\u003e, IPropertyBuilder\u003cbool\u003e\u003e configure)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            var context = new PropertyContext\u003cbool\u003e(self, ZXing.Net.Maui.Controls.CameraView.IsTorchOnProperty);\n            configure(context).Build();\n            return self;\n        }\n        \n        public static SettersContext\u003cT\u003e IsTorchOn\u003cT\u003e(this SettersContext\u003cT\u003e self,\n            bool isTorchOn)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            self.XamlSetters.Add(new Setter { Property = ZXing.Net.Maui.Controls.CameraView.IsTorchOnProperty, Value = isTorchOn });\n            return self;\n        }\n        \n        public static SettersContext\u003cT\u003e IsTorchOn\u003cT\u003e(this SettersContext\u003cT\u003e self, Func\u003cPropertySettersContext\u003cbool\u003e, IPropertySettersBuilder\u003cbool\u003e\u003e configure)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            var context = new PropertySettersContext\u003cbool\u003e(self.XamlSetters, ZXing.Net.Maui.Controls.CameraView.IsTorchOnProperty);\n            configure(context).Build();\n            return self;\n        }\n        \n        public static T OnFrameReady\u003cT\u003e(this T self, System.EventHandler\u003cZXing.Net.Maui.CameraFrameBufferEventArgs\u003e handler)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            self.FrameReady += handler;\n            return self;\n        }\n        \n        public static T OnFrameReady\u003cT\u003e(this T self, System.Action\u003cT\u003e action)\n            where T : ZXing.Net.Maui.Controls.CameraView\n        {\n            self.FrameReady += (o, arg) =\u003e action(self);\n            return self;\n        }\n        \n}\n\n```\n\nFor example, let's write the sample code for the **TextField and SKLottieView Controls**:\n\n```csharp\nnew TextField()\n.Title(\"Password\")\n.TitleColor(Colors.LightGray)\n.AccentColor(Colors.CadetBlue)\n.TextColor(Colors.White)\n.IsPassword(true),\n\nnew SKLottieView()\n.Source(new SKFileLottieImageSource().File(\"iconapp.json\"))\n.RepeatCount(-1)\n.HeightRequest(250)\n.WidthRequest(250)\n```\n\nWith the **MauiMarkupAttachedPropAttribute**, you can easily create extension methods for **AttachedProperties** within Control classes from third-party libraries.\n**The constructor's first parameter takes the type of the Control class, the second parameter takes the name of the AttachedProperty, the third parameter takes the value type that the AttachedProperty can accept, and the fourth parameter takes the type to which the AttachedProperty will be applied.**\n\nExample usage:\n\n```csharp\n[MauiMarkupAttachedProp(typeof(InputKit.Shared.Controls.FormView), nameof(InputKit.Shared.Controls.FormView.IsSubmitButtonProperty), typeof(bool), typeof(Button))]\n[MauiMarkup(typeof(InputKit.Shared.Controls.FormView))]\npublic class MyFormView { }\n```\nOR\n```csharp\n\nusing Microsoft.Extensions.Logging;\nusing FmgLib.MauiMarkup;\n\nnamespace MauiApp1\n{\n    [MauiMarkupAttachedProp(typeof(InputKit.Shared.Controls.FormView), nameof(InputKit.Shared.Controls.FormView.IsSubmitButtonProperty), typeof(bool), typeof(Button))]\n    [MauiMarkup(typeof(InputKit.Shared.Controls.FormView))]\n    public static class MauiProgram\n    {\n        public static MauiApp CreateMauiApp()\n        {\n            var builder = MauiApp.CreateBuilder();\n            builder\n                .UseMauiApp\u003cApp\u003e()\n                .ConfigureFonts(fonts =\u003e\n                {\n                    fonts.AddFont(\"OpenSans-Regular.ttf\", \"OpenSansRegular\");\n                    fonts.AddFont(\"OpenSans-Semibold.ttf\", \"OpenSansSemibold\");\n                });\n\n#if DEBUG\n    \t\tbuilder.Logging.AddDebug();\n#endif\n            return builder.Build();\n        }\n    }\n}\n```\n\nThe usage of the AttachedProperty in the Button class will be as follows:\n```csharp\nnew Button()\n.Text(\"Login\")\n.FontAttributes(Bold)\n.FormViewIsSubmitButton(true)\n```\n\n\u003cbr\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eLocalization (Json File)\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\nIn the MauiProgram.cs file,\n\n```CSharp\nbuilder\n    .UseMauiApp\u003cApp\u003e()\n    .UseMauiMarkupLocalization();\n```\nshould be added.\n\nIn your main project you should have a language file of type json. The translation will be read from this file and imported.\nIf you do not specify the path to the file(s) in the parameter ( \n\n```CSharp\nbuilder\n    .UseMauiApp\u003cApp\u003e()\n    .UseMauiMarkupLocalization();\n  //.UseMauiMarkupLocalization(defaultLang:\"en-US\"); // or\n  //.UseMauiMarkupLocalization(defaultLang:\"en-US\", \"Loc1.json\", \"Loc2.json\"); // or\n```\n), will look for a json file named `Localization.json` in the home directory.\n\nif you give one or more parameters like\n```CSharp\nbuilder\n    .UseMauiApp\u003cApp\u003e()\n    .UseMauiMarkupLocalization(filePaths: \"Localization1.json\", \"Localization2.json\", \"/Languages/Temp1.json\");\n```\n\nit will read json files in given file paths.\n\n**The critical point here is to select ```Build Action: MauiAsset``` for json files.**\n\nProper json format:\n\n```json\n{\n  \"Hello\": {\n    \"tr-TR\": \"Merhaba Dünya!\",\n    \"en-US\": \"Hello World!\"\n  },\n  \"Msg\": {\n    \"tr-TR\": \"Deneme amaçlı yapılmıştır.\",\n    \"en-US\": \"It was made for testing purposes.\"\n  }\n}\n```\n\nInstead of 'keyWord' keywords, you can use any word or phrase(s) you want. You don't have any Regex limitations.\n\nYou can also change the 'tr-TR' and 'en-US' language keys with words or sentences as you wish. But it is recommended to use expressions such as 'en-US', 'tr-TR', 'fr-FR'.\n\nYou can change the language of the system with the following statement: `Translator.Instance.ChangeCulture(CultureInfo.GetCultureInfo(\"en-US\"));`\n\n\nYou can simply use \n```CSharp\nnew Label()\n.Text(e =\u003e e.Translate(\"Hello\"))\n.FontSize(32)\n.CenterHorizontal()\n.SemanticHeadingLevel(SemanticHeadingLevel.Level1),\n\nnew Label()\n.Text(e =\u003e e.Translate(\"Msg\"))\n.FontSize(18)\n.CenterHorizontal()\n.SemanticDescription(e =\u003e e.Translate(\"Msg\"))\n.SemanticHeadingLevel(SemanticHeadingLevel.Level1),\n\nnew VerticalStackLayout()\n.Center()\n.Children(\n    new RadioButton()\n    .IsChecked(Translator.Instance.CurrentCulture.Name == \"tr-TR\")\n    .Content(\"tr-TR\")\n    .OnCheckedChanged((sender, e) =\u003e\n    {\n        Translator.Instance.ChangeCulture(CultureInfo.GetCultureInfo(\"tr-TR\"));\n    }),\n    new RadioButton()\n    .IsChecked(Translator.Instance.CurrentCulture.Name == \"en-US\")\n    .Content(\"en-US\")\n    .OnCheckedChanged((sender, e) =\u003e\n    {\n        Translator.Instance.ChangeCulture(CultureInfo.GetCultureInfo(\"en-US\"));\n    })\n)\n``` \nin the code.\n\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eLocalization (Resx File)\u003c/b\u003e\u003c/summary\u003e\n    \n\u003cbr\u003e\n\u003cbr\u003e\nIn the MauiProgram.cs file,\n\n```CSharp\nbuilder\n    .UseMauiApp\u003cApp\u003e()\n    .UseMauiMarkupLocalizationWithResx(AppResources.ResourceManager);\n    // .UseMauiMarkupLocalizationWithResx(AppResources.ResourceManager, \"en-US\"); // set default lang\n```\nshould be added.\n\nYou should have source files with the extension resx in your project. The translation will be read from this file and imported.\nThen, in **MauiProgram.cs**, pass your `ResourceManager` value as a parameter to `UseMauiMarkupLocalizationWithResx`.\n\n\nYou can also change the 'tr-TR' and 'en-US' language keys with words or sentences as you wish. But it is recommended to use expressions such as 'en-US', 'tr-TR', 'fr-FR'.\n\nYou can change the language of the system with the following statement: `TranslatorResx.Instance.ChangeCulture(CultureInfo.GetCultureInfo(\"en-US\"));`\n\nYou can simply use \n```CSharp\nnew Label()\n.Text(e =\u003e e.TranslateResx(\"Hello\"))\n.FontSize(32)\n.CenterHorizontal()\n.SemanticHeadingLevel(SemanticHeadingLevel.Level1),\n\nnew Label()\n.Text(e =\u003e e.TranslateResx(nameof(AppResource.Msg)))\n.FontSize(18)\n.CenterHorizontal()\n.SemanticDescription(e =\u003e e.TranslateResx(\"Msg\"))\n.SemanticHeadingLevel(SemanticHeadingLevel.Level1),\n\nnew VerticalStackLayout()\n.Center()\n.Children(\n    new RadioButton()\n    .IsChecked(TranslatorResx.Instance.CurrentCulture.Name == \"tr-TR\")\n    .Content(\"tr-TR\")\n    .OnCheckedChanged((sender, e) =\u003e\n    {\n        TranslatorResx.Instance.ChangeCulture(CultureInfo.GetCultureInfo(\"tr-TR\"));\n    }),\n    new RadioButton()\n    .IsChecked(TranslatorResx.Instance.CurrentCulture.Name == \"en-US\")\n    .Content(\"en-US\")\n    .OnCheckedChanged((sender, e) =\u003e\n    {\n        TranslatorResx.Instance.ChangeCulture(CultureInfo.GetCultureInfo(\"en-US\"));\n    })\n)\n``` \nin the code.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eGeneral Example Code\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n```csharp\n\nusing Microsoft.Maui.Layouts;\nusing FmgLib.MauiMarkup;\n\nnamespace MyOrderApp.Views;\n\npublic partial class HomePage : BasePage\u003cHomePageViewModel\u003e\n{\n    public HomePage(HomePageViewModel viewModel) : base(viewModel, \"Home Page\")\n    {\n    }\n\n    public override void Build()\n    {\n        this\n        .Content(\n            new VerticalStackLayout()\n            .Padding(10)\n            .Children(\n                new SearchBar()\n                .Placeholder(\"Ürünlerde Ara.\")\n                .Margin(10)\n                .Assign(out var search)\n                .SearchCommand(BindingContext.SearchCommand)\n                .Bind(SearchBar.SearchCommandParameterProperty, \"Text\", source: search),\n\n                new Frame()\n                .CornerRadius(15)\n                .BackgroundColor(Colors.Blue)\n                .BorderColor(Colors.Blue)\n                .HeightRequest(150)\n                .Margin(15,7)\n                .Padding(0)\n                .Content(\n                    new Grid()\n                    .ColumnDefinitions(e =\u003e e.Star(5).Star(5))\n                    .RowDefinitions(e =\u003e e.Star(5).Star(5))\n                    .Children(\n                        new Frame()\n                        .Row(0)\n                        .Column(0)\n                        .Margin(0,20,0,0)\n                        .Padding(0)\n                        .CornerRadius(0)\n                        .BackgroundColor(Colors.DarkBlue)\n                        .BorderColor(Colors.DarkBlue)\n                        .Content(\n                            new Label()\n                            .Text(\"%50 İndirim\")\n                            .TextColor(Colors.White)\n                            .FontAttributes(FontAttributes.Bold)\n                            .FontSize(20)\n                            .Center()\n                        ),\n\n                        new Label()\n                        .Text(\"Tüm Unlu Mamüllerde her gün saat 21:00'dan sonra!\")\n                        .FontSize(12)\n                        .Row(1)\n                        .Column(0)\n                        .TextColor(Colors.White)\n                        .FontAttributes(FontAttributes.Italic)\n                        .Margin(10,3,0,0),\n\n                        new Image()\n                        .Source(\"white_board.png\")\n                        .Row(0)\n                        .Column(1)\n                        .RowSpan(2)\n                        .SizeRequest(150,100)\n                        .Opacity(.8)\n                    )\n                ),\n\n                new Grid()\n                .ColumnDefinitions(e =\u003e e.Star(7).Star(3))\n                .FillHorizontal()\n                .Padding(10)\n                .Children(\n                    new Label()\n                    .Text(\"Son Ürünler\")\n                    .FontAttributes(FontAttributes.Bold)\n                    .FontSize(18)\n                    .CenterVertical()\n                    .Column(0)\n                    .AlignLeft(),\n\n\n                    new Label()\n                    .Text(\"Tümünü Gör\")\n                    .FontSize(15)\n                    .CenterVertical()\n                    .Column(1)\n                    .AlignRight()\n                    .TextDecorations(TextDecorations.Underline)\n                    .GestureRecognizers(\n                        new TapGestureRecognizer()\n                        .Command(BindingContext.GotoAllProductsCommand)\n                    )\n                ),\n\n                new CollectionView()\n                .SelectionMode(SelectionMode.None)\n                .Bind(CollectionView.ItemsSourceProperty, \"Products\")\n                .ItemsLayout(new LinearItemsLayout(ItemsLayoutOrientation.Horizontal).ItemSpacing(10))\n                .EmptyView(\n                    new VerticalStackLayout()\n                    .Children(\n                        new Label()\n                        .Text(\"Kayıt Yoktur.\")\n                        .TextColor(Colors.Red)\n                        .FontAttributes(FontAttributes.Bold)\n                        .FontSize(18)\n                    )\n                    .Center()\n                )\n                .ItemTemplate(() =\u003e\n                    new Frame()\n                    .CornerRadius(15)\n                    .BorderColor(Colors.LightGray)\n                    .BackgroundColor(Colors.LightGray)\n                    .MinimumHeightRequest(200)\n                    .MaximumWidthRequest(200)\n                    .Padding(5)\n                    .Content(\n                        new Grid()\n                        .RowDefinitions(e =\u003e e.Star(1).Star(6).Star(2).Star(1))\n                        .Padding(5)\n                        .Children(\n                            new Grid()\n                            .Row(0)\n                            .ColumnDefinitions(e =\u003e e.Star(6).Star(4))\n                            .Children(\n                                new ImageButton()\n                                .Bind(ImageButton.SourceProperty, nameof(ProductVM.IsFavorite), converter: new BoolToFavoriteImageConverter())\n                                .BackgroundColor(Colors.Transparent)\n                                .AlignLeft()\n                                .SizeRequest(30, 30)\n                                .Command(BindingContext.ChangeFavoriteCommand)\n                                .Bind(ImageButton.CommandParameterProperty, \".\"),\n\n                                new Frame()\n                                .CornerRadius(20)\n                                .HeightRequest(25)\n                                .WidthRequest(50)\n                                .Padding(0)\n                                .BackgroundColor(Colors.Red)\n                                .BorderColor(Colors.Red)\n                                .Column(1)\n                                .Bind(Microsoft.Maui.Controls.Frame.IsVisibleProperty, nameof(ProductVM.IsDiscount))\n                                .Content(\n                                    new Label()\n                                    .Bind(Label.TextProperty, nameof(ProductVM.DiscountRate))\n                                    .FontSize(11)\n                                    .FontAttributes(FontAttributes.Bold)\n                                    .TextColor(Colors.White)\n                                    .Center()\n                                )\n                            ),\n\n                            new Image()\n                            .Bind(Image.SourceProperty, nameof(ProductVM.Image))\n                            .SizeRequest(80,80)\n                            .Row(1)\n                            .CenterHorizontal(),\n\n                            new VerticalStackLayout()\n                            .Row(2)\n                            .Children(\n                                new Label()\n                                .Bind(Label.TextProperty, nameof(ProductVM.Name))\n                                .FontAttributes(FontAttributes.Bold)\n                                .FontSize(11)\n                                .AlignLeft()\n                                .LineBreakMode(LineBreakMode.TailTruncation)\n                                .FontAutoScalingEnabled(true),\n\n                                new HorizontalStackLayout()\n                                .Spacing(2)\n                                .Children(\n                                    new Label()\n                                    .Bind(Label.TextProperty, nameof(ProductVM.Price))\n                                    .Bind(Label.TextDecorationsProperty, nameof(ProductVM.IsDiscount), converter: new BoolToTextDecorationConverter())\n                                    .Bind(Label.FontSizeProperty, nameof(ProductVM.IsDiscount), converter: new BoolToFontSizeConverter())\n                                    .FontAttributes(FontAttributes.Bold)\n                                    .CenterVertical(),\n\n                                    new Label()\n                                    .TextColor(Colors.Red)\n                                    .FontAttributes(FontAttributes.Bold)\n                                    .CenterVertical()\n                                    .Bind(Label.IsVisibleProperty, nameof(ProductVM.IsDiscount))\n                                    .Bind(Label.TextProperty, nameof(ProductVM.DiscountPrice)),\n\n                                    new Label()\n                                    .Text(\"/\")\n                                    .FontSize(10)\n                                    .CenterVertical()\n                                    .TextColor(Colors.DarkSlateGray),\n\n                                    new Label()\n                                    .FontSize(10)\n                                    .CenterVertical()\n                                    .TextColor(Colors.DarkSlateGray)\n                                    .Bind(Label.TextProperty, nameof(ProductVM.Unit))\n                                )\n                            ),\n\n                            new Button()\n                            .Row(3)\n                            .Margin(new Thickness(0,5,0,0))\n                            .Padding(0)\n                            .Text(\"Sepete Ekle\")\n                            .BackgroundColor(Colors.Green)\n                            .FontSize(12)\n                            .FontAttributes(FontAttributes.Bold)\n                            .CenterHorizontal()\n                            .HeightRequest(35)\n                            .WidthRequest(100)\n                            .Command(BindingContext.AddProductBasketCommand)\n                            .Bind(Button.CommandParameterProperty, \".\")\n                        )\n                    )\n                ),\n\n                new Grid()\n                .ColumnDefinitions(e =\u003e e.Star(7).Star(3))\n                .FillHorizontal()\n                .Padding(10)\n                .Children(\n                    new Label()\n                    .Text(\"Kategoriler\")\n                    .FontAttributes(FontAttributes.Bold)\n                    .FontSize(18)\n                    .CenterVertical()\n                    .Column(0)\n                    .AlignLeft(),\n\n\n                    new Label()\n                    .Text(\"Tümünü Gör\")\n                    .FontSize(15)\n                    .CenterVertical()\n                    .Column(1)\n                    .AlignRight()\n                    .TextDecorations(TextDecorations.Underline)\n                    .GestureRecognizers(\n                        new TapGestureRecognizer()\n                        .Command(BindingContext.GotoAllCategoriesCommand)\n                    )\n                ),\n\n                new FlexLayout()\n                .ItemsSources(BindingContext.Categories)\n                .Assign(out var flex)\n                .Wrap(FlexWrap.Wrap)\n                .FlexBasis(FlexBasis.Auto)\n                .ItemTemplates(new DataTemplate(() =\u003e \n                    new Frame()\n                    .CornerRadius(15)\n                    .BorderColor(Colors.LightGray)\n                    .BackgroundColor(Colors.LightGray)\n                    .MinimumHeightRequest(30)\n                    .WidthRequest(180)\n                    .Padding(0)\n                    .Margin(new Thickness(1,0,5,5))\n                    .FlexBasis(FlexBasis.Auto)\n                    .Content(\n                        new Grid()\n                        .ColumnDefinitions(e =\u003e e.Star(3).Star(7))\n                        .Padding(5)\n                        .Children(\n                            new Image()\n                            .Bind(Image.SourceProperty, nameof(SubCategoryVM.Icon))\n                            .SizeRequest(30,30)\n                            .Column(0)\n                            .CenterVertical(),\n\n                            new Label()\n                            .Bind(Label.TextProperty, nameof(SubCategoryVM.Name))\n                            .TextColor(Colors.CornflowerBlue)\n                            .FontAttributes(FontAttributes.Bold)\n                            .FontSize(12)\n                            .Column(1)\n                            .FontAutoScalingEnabled(true)\n                            .CenterVertical()\n                        )\n                    )\n                ))\n            )\n            .FillHorizontal()\n        );\n    }\n}\n\n```\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmglib%2Ffmglib.mauimarkup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffmglib%2Ffmglib.mauimarkup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmglib%2Ffmglib.mauimarkup/lists"}