Giter Club home page Giter Club logo

maui's Introduction

.NET Multi-platform App UI (.NET MAUI)

Build Status Build Status

.NET Multi-platform App UI (.NET MAUI) is a cross-platform framework for creating mobile and desktop apps with C# and XAML. Using .NET MAUI, you can develop apps that can run on Android, iOS, iPadOS, macOS, and Windows from a single shared codebase.

Getting Started

Overview

.NET Multi-platform App UI (.NET MAUI) is the evolution of Xamarin.Forms that expands capabilities beyond mobile Android and iOS into desktop apps for Windows and macOS. With .NET MAUI, you can build apps that perform great for any device that runs Windows, macOS, Android, & iOS from a single codebase. Coupled with Visual Studio productivity tools and emulators, .NET and Visual Studio significantly speed up the development process for building apps that target the widest possible set of devices. Use a single development stack that supports the best of breed solutions for all modern workloads with a unified SDK, base class libraries, and toolchain. Read More

.NET MAUI Weather App on all platforms

Current News

Follow the .NET MAUI Blog and visit the News wiki page for more news and updates.

FAQs

Do you have questions? Do not worry, we have prepared a complete FAQ answering the most common questions.

How to Engage, Contribute, and Give Feedback

Some of the best ways to contribute are to try things out, file issues, join in design conversations, and make pull-requests. Proposals for changes specific to MAUI can be found here for discussion.

See CONTRIBUTING, CODE-OF-CONDUCT and the Development Guide.

maui's People

Contributors

adrianknight89 avatar andreimisiukevich avatar clancey avatar davidortinau avatar dependabot[bot] avatar dimonovdd avatar dotnet-maestro[bot] avatar drasticactions avatar eilon avatar github-actions[bot] avatar hartez avatar jamesmontemagno avatar jfversluis avatar jonathanpeppers avatar jonlipsky avatar jsuarezruiz avatar kingces95 avatar mandel-macaque avatar mattleibow avatar myroot avatar pauldipietro avatar paymicro avatar pjcollins avatar pureween avatar rachelkang avatar redth avatar rmarinho avatar rookiejava avatar samhouts avatar stephanedelcroix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

maui's Issues

About the 1675 open bugs in Xamarin.Forms

Please read this comment from @davidortinau

#109 (comment)

Reading through here I'm wondering what I can learn here to improve the quality of Xamarin.Forms. I would love to return to @Happypig375's original question:

Any thoughts on how to improve?

One of our main goals between now and shipping .NET MAUI is improving the foundation, starting point. For this reason we are spending much of our current sprints on CollectionView issues, and we are proposing to pause feature developer in Xamarin.Forms 5 so we have from Sept 2020 to Nov 2021 to shift more focus to issue resolution.

This is all visible on our sprint project boards.

Original Description

Xamarin.Forms is known to be buggy. It currently has 1675 open bugs, which is on track to surpass mono's 1676 open issues. By comparing the numbers, it is easy to see that Xamarin.Forms is buggier than the "historically buggy" mono framework.

Now that MAUI's source code was copied from Xamarin.Forms, it means that MAUI starts out to be equally as buggy as Xamarin.Forms. Everyone seem to focus on making the MAUI architecture as bug-free as possible by following Flutter, but the fact that Xamarin.Forms bugs are fixed very slowly, even for bugs with high impact seems to be ignored. e.g.

And opening a pull request can still result in the request being stuck in limbo until an official from Xamarin spares the time to take a look at the files changed.

As time progresses, people will start to depend on the bug, resulting in the bugfix being perceived as introducing a new bug.

Xamarin.Forms was buggy in 2015, Xamarin.Forms was buggy in 2018 and Xamarin.Forms will still be buggy in 2021 when MAUI is released if bugs are fixed this slowly.

This is simply unacceptable for those working with a tight deadline and time need to be wasted on finding workarounds and applying them.

With MAUI, we should have a bugfixing process that is as fast as possible. Any thoughts on how to improve?

[Spec] Cross-Platform LifeCycle

LifeCycle

This spec currently illustrates the types of events we are looking to surface with .NET MAUI

The platform level tie ins are purposefully left blank so that we can define purpose and use cases without getting stuck inside platform paradigms. By design .NET MAUI will allow users to hook into native life cycle events without the complexities of wiring up a renderer so if users require finer platform level hooks they can break out of the xplat APIs easily and use Mapper/Handler structures to hook in.

Application (Work in Progress)

Event Description Use Cases
Creating Before the native concept of the Application is created (Not sure if this is possible?). Not sure?
Created After the native concept of an Application is created and before any windows have been created Register Windows or other services that are needed before a window comes into existence
Resuming Application is Starting up or resuming from the background. This fires after created and it will also fire after coming back from the background Wire Up services or update your application based on it coming into existence
Resumed Currently Active window has finished activating and application is ready for interacting
Pausing App is going into the Background
Paused App has gone into the Background (Is this possible on all platforms?)
Stopping App is Closing (Is this possible on non desktop platforms?)
Stopped All Windows have been closed and everything is cleaned up (Is this Possible?)

Window

#1720

Page

  • This API doesn't have Appearing/Appeared currently because those APIs are currently very inconsistent and overloaded. Appearing/Appeared will most likely be a combination of the events provided here in order to limit breaking.

  • Currently these events will fire for the following scenarios

    • Tabbed Navigation
    • Push/pop Navigation
  • These events will not fire during app resume/backgrounding

  • Page will inherit from View so all of the events that are on View will also be part of Page

Event Description Use Cases
NavigatingTo Page is going to be navigated to and fires after NavigatingFrom.
NavigatedTo Page has been navigated to via what we currently call "NavigationPage".
NavigatingFrom Fires before the NavigatingTo fires on the destination page.
NavigatedFrom Fires after the NavigatedTo fires on the destination page.

View/VisualElement

Handler Life Cycle

Event Description Use Cases
ParentChanging parent is about to be set on this view This tells you that the view is about to get connected to an xplat visual tree
ParentChanged parent has changed on this view

Parent Changing/Changed

Native helpers (WiP)

Can we create native mappers that tie into all native life cycle events? How can we provide a mapper for UIView.LayoutSubViews for example

[Spec] Drop .NET Standard 1.0 support

Description

Remove .NET Standard 1.0 support.

Forms currently supports .NET Standard 1.0 in order to support older Windows devices and PCL projects. .NET Standard projects have been the default for Forms for a while now, and eventually moving to newer .NET versions is going to force this transition anyway. Dropping 1.0 support allows us to simplify the builds, project loading, test matrix, and stop supporting some custom 1.0 code.

Backward Compatibility

Users who are still using PCL projects will need to convert them to .NET Standard projects. UWP builds targeted at 14393 and earlier will need to be updated to at least 16299 .

Difficulty : Low

Mostly just deleting code - removing all of the NETSTANDARD1_0 #if checks and removing the .NET Stanard sections from the nuspec files.

[Enhancement] Better support for C# 8.0 nullable reference feature

Summary

Hello, I'm a WPF and UWP developer. While developing apps, I always don't know if the return value is null and got a NullPointerException after I run the app. I hope the maui API can use the C# 8.0 nullable reference feature to tell the developers if the return or input value can be null.

API Changes

It is a compiler feature, I think there are no API changes.

Intended Use Case

Like this:

DependencyObject? parent = MyButton.Parent; // The parent maybe null.
ItemCollection? items = MyItemsControl.Items; // Sometimes, the items will be null.

[Spec] AppBar

AppBar

An app bar consists of a toolbar and potentially other views. Expose one or more actions.

The main benefit of using the appbar is being able to customize everything. Customization options like:

  • Custom app bar height.
  • Include any content without restrictions or limitations (margins, size, etc.).
  • Transparent appbar.
  • Etc.

NOTE: AppBar is a cross-platform view that takes over when native navbar hit their limits, such as adding custom content, positioning with layouts, etc.

In Maui, the app bar are typically used in the Shell.AppBar property, which places the app bar as a fixed-height widget at the top of the screen.

appbar

API

Next, a list with the AppBar properties and events.

Properties

Property Type Description
Placement AppBarPlacement The AppBar placement (top or bottom).
BarHeight double Define the app bar height.
BarBackground Brush A brush that provides the background.
BarBackgroundImage ImageSource An ImageSource that provides the background.
BarTextColor Color The color used in the texts (title, etc.).
NavigationIcon ImageSource An ImageSource that provides the navigation icon (back button, etc).
BackButtonTitle string Define the app bar back button title.
BorderColor Color The app bar border color.
BorderThickness Thickness The appbar border width in every side.
FontFamily string The font family used in the app bar texts.
FontAttributes FontAttributes The font attributes used in the app bar texts.
FontSize double The font size used in the app bar texts.
TitleView View Display any Maui View in the app bar.
BackCommand ICommand Command executed navigating back.
BackCommandParameter object The command parameter used navigating back.

Events

Event Description
BackTapped Event that is raised when the user navigate back.

Scenarios

Let's see some samples covering common scenarios.

Simple app bar

Let's see a basic example:

<Shell>
     <Shell.AppBar>
         <AppBar />
     </Shell.AppBar>
    ...
</Shell>

Custom app bar

Customizing the appearance using a transparent bar with a custom height and custom content (TitleView).

<Shell>
     <Shell.AppBar>
        <AppBar  
            BarHeight="120"
            BarBackgroundColor="Transparent">
            <AppBar.TitleView>
            ...
            </AppBar.TitleView>
        </AppBar>
     </Shell.AppBar>
    ...
</Shell>

Placement

A top app bar (default placement) displays navigation and actions at the top of mobile screens.

<Shell>
     <Shell.AppBar
          Placement="Top">
         <AppBar />
     </Shell.AppBar>
    ...
</Shell>

appbar-top

A bottom app bar displays navigation and actions at the bottom of mobile screens.

<Shell>
     <Shell.AppBar
          Placement="Bottom">
         <AppBar />
     </Shell.AppBar>
    ...
</Shell>

appbar-bottom

Using Styles

Can customize the appearance of the tab content, tab strip, tab item, etc. using XAML styles or CSS.

Using XAML:

<Style
    x:Key="AppBarStyle"
    TargetType="AppBar">
    <Setter
        Property="BarHeight"
        Value="120" />
    <Setter
        Property="BarBackgroundColor"
        Value="Transparent" />
</Style>

Using CSS:

.appBarStyle {
  background: transparent;
  height: 120px;
}

Difficulty : Medium

[Spec] Pages Status

Here you find a list of all Pages with their (public) APIs and their status. If you find anything that needs an update, please feel free to do so.

Icon Description
⚠️ Pending
Underway
Done
💔 Never implemented in Forms for this platform

⚠️ ContentPage

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BackgroundColor ⚠️ ⚠️ ⚠️ ⚠️
BackgroundImage ⚠️ ⚠️ ⚠️ ⚠️
DisplayActionSheet ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
DisplayAlert ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Icon ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsBusy ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnAppearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnDisappearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Padding ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Title ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ToolbarItems ⚠️ ⚠️ ⚠️ ⚠️

⚠️ MasterDetailPage

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BackgroundColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Detail ⚠️ ⚠️ ⚠️ ⚠️
IsGestureEnabled ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsPresented ⚠️ ⚠️ ⚠️ ⚠️
Master ⚠️ ⚠️ ⚠️ ⚠️
MasterBehavior ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnAppearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnDisappearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Padding ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ NavigationPage

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BackButtonTitle ⚠️ ⚠️ ⚠️ ⚠️
BackgroundColor ⚠️ ⚠️ ⚠️ ⚠️
BackgroundImage ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BarBackgroundColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BarTextColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SelectedItem ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Icon ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsBusy ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ItemsSource ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ItemTemplate ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnAppearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnDisappearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Padding ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Title ⚠️ ⚠️ ⚠️ ⚠️

⚠️ TabbedPage

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BackgroundColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BackgroundImage ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BarBackgroundColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BarTextColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Children ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
CurrentPage ⚠️ ⚠️ ⚠️ ⚠️
Icon ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsBusy ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ItemsSource ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ItemTemplate ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnAppearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
OnDisappearing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Padding ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SelectedTabColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SelectedItem ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Title ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
UnselectedTabColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

[Spec] Add IDispatcher to the IAnimatable interface

Description

Add IDispatcher to IAnimatable interface.

The animation methods in Forms automatically handle UI thread marshaling for the user. Unfortunately, they do this using the static Device.IsInvokeRequired and Device.BeginInvokeOnMainThread, which are incompatible with multi-window applications on some platforms. To address this, we can add a dispatcher to the IAnimatable interface to use for these thread checks.

API

On Xamarin.Forms.IAnimatable, add IDispatcher Dispatcher { get; }

Backward Compatibility

Anyone who has implemented the IAnimatable interface will need to add an IDispatcher to their implementation.

Difficulty : Low

The main implemnentation of IAnimatable in Forms is VisualElement, which already has an IDispatcher. The other implementations (Tizen's NavigationDrawer and a couple of test classes) will need to add it as well. The explicit type check in the DoAction method of AnimationExtensions will need to be removed, and the use of the static Device methods will need to be replaced with Dispatcher.

[Spec] Remove members marked with Obsolete attribute

Description

Remove members marked with the Obsolete attribute.

Core

Class Member to Remove Removed? PR
Application LogWarningsToApplicationOutput xamarin/Xamarin.Forms#13813
BindableObject GetValues xamarin/Xamarin.Forms#13813
BindableObjectExtensions SetBinding xamarin/Xamarin.Forms#13813
BindableProperty Create xamarin/Xamarin.Forms#13813
BindableProperty CreateAttached xamarin/Xamarin.Forms#13813
BindableProperty CreateAttachedReadOnly xamarin/Xamarin.Forms#13813
BindableProperty CreateReadOnly xamarin/Xamarin.Forms#13813
Binding Create xamarin/Xamarin.Forms#13813
Button BorderRadius xamarin/Xamarin.Forms#13813
Button Image xamarin/Xamarin.Forms#13813
Button BorderRadiusProperty xamarin/Xamarin.Forms#13813
Button ImageProperty xamarin/Xamarin.Forms#13813
EntryCell XAlign xamarin/Xamarin.Forms#13813
Label XAlign xamarin/Xamarin.Forms#13813
EntryCell XAlignProperty xamarin/Xamarin.Forms#13813
Label XAlignProperty xamarin/Xamarin.Forms#13813
Color Fuschia xamarin/Xamarin.Forms#13813
Device OnPlatform xamarin/Xamarin.Forms#13813
Device OnPlatform xamarin/Xamarin.Forms#13813
Device OpenUri xamarin/Xamarin.Forms#13813
Device OS xamarin/Xamarin.Forms#13813
Element ParentView #1644
Element Platform xamarin/Xamarin.Forms#13813
IElementController Platform xamarin/Xamarin.Forms#13813
Element PlatformSet xamarin/Xamarin.Forms#13813
IElementController PlatformSet xamarin/Xamarin.Forms#13813
Font BoldSystemFontOfSize xamarin/Xamarin.Forms#13813
Font BoldSystemFontOfSize xamarin/Xamarin.Forms#13813
Frame OutlineColor xamarin/Xamarin.Forms#13813
Frame OutlineColorProperty xamarin/Xamarin.Forms#13813
IExtendedTypeConverter ConvertFrom xamarin/Xamarin.Forms#13813
IMenuItemController IsEnabledPropertyName xamarin/Xamarin.Forms#13813
MenuItem IsEnabledPropertyName xamarin/Xamarin.Forms#13813
ItemTappedEventArgs .ctor xamarin/Xamarin.Forms#13813
ItemVisibilityEventArgs .ctor xamarin/Xamarin.Forms#13813
Label Font xamarin/Xamarin.Forms#13813
Label YAlign xamarin/Xamarin.Forms#13813
Label YAlignProperty xamarin/Xamarin.Forms#13813
Layout GetSizeRequest #1644
VisualElement GetSizeRequest #1644
MenuItem Icon xamarin/Xamarin.Forms#13813
Page Icon xamarin/Xamarin.Forms#13813
MenuItem IconProperty xamarin/Xamarin.Forms#13813
Page IconProperty xamarin/Xamarin.Forms#13813
NavigationPage GetTitleIcon xamarin/Xamarin.Forms#13813
NavigationPage SetTitleIcon xamarin/Xamarin.Forms#13813
NavigationPage Tint xamarin/Xamarin.Forms#13813
NavigationPage TintProperty xamarin/Xamarin.Forms#13813
NavigationPage TitleIconProperty xamarin/Xamarin.Forms#13813
OnPlatform<T> Android xamarin/Xamarin.Forms#13813
OnPlatform<T> iOS xamarin/Xamarin.Forms#13813
OnPlatform<T> WinPhone xamarin/Xamarin.Forms#13813
Page DisplayPromptAsync xamarin/Xamarin.Forms#13813
Page BackgroundImage xamarin/Xamarin.Forms#13813
Page BackgroundImageProperty xamarin/Xamarin.Forms#13813
ResourceDictionary MergedWith xamarin/Xamarin.Forms#13813
SelectedItemChangedEventArgs .ctor xamarin/Xamarin.Forms#13813
IShellSectionController SendPopped xamarin/Xamarin.Forms#13813
IShellSectionController SendPopping xamarin/Xamarin.Forms#13813
IShellSectionController SendPopped xamarin/Xamarin.Forms#13813
Slider ThumbImage xamarin/Xamarin.Forms#13813
Slider ThumbImageProperty xamarin/Xamarin.Forms#13813
Span Font xamarin/Xamarin.Forms#13813
Span ForegroundColorProperty xamarin/Xamarin.Forms#13813
TapGestureRecognizer .ctor xamarin/Xamarin.Forms#13813
TapGestureRecognizer .ctor xamarin/Xamarin.Forms#13813
TapGestureRecognizer TappedCallback xamarin/Xamarin.Forms#13813
TapGestureRecognizer TappedCallbackParameter xamarin/Xamarin.Forms#13813
TapGestureRecognizer TappedCallbackProperty xamarin/Xamarin.Forms#13813
TapGestureRecognizer TappedCallbackParameterProperty xamarin/Xamarin.Forms#13813
ToolbarItem Name xamarin/Xamarin.Forms#13813
ToolbarItem Activated xamarin/Xamarin.Forms#13813
TypeConverter ConvertFrom xamarin/Xamarin.Forms#13813
TypeConverter ConvertFrom xamarin/Xamarin.Forms#13813
StyleSheets.StyleSheet FromAssemblyResource xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage GetBarItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage SetBarItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage GetBarItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage SetBarItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage BarItemColorProperty xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage GetBarSelectedItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage SetBarSelectedItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage SetBarSelectedItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage GetBarSelectedItemColor xamarin/Xamarin.Forms#13813
PlatformConfiguration.AndroidSpecific.TabbedPage BarSelectedItemColorProperty xamarin/Xamarin.Forms#13813
Internals.IPlatform GetNativeSize Don't know, but IPlatform is gone, so...
Internals.NavigationRequestedEventArgs .ctor xamarin/Xamarin.Forms#13813
Internals.NavigationRequestedEventArgs Realize xamarin/Xamarin.Forms#13813
Internals.ResourceLoader CanProvideContentFor #1637
Internals.ResourceLoader ResourceProvider #1637
Internals.PromptArguments .ctor xamarin/Xamarin.Forms#13813
Internals.TypedBinding<TSource, TProperty> .ctor xamarin/Xamarin.Forms#13813

Maps

Class Member to Remove Removed? PR
Maps.Pin SendTap xamarin/Xamarin.Forms#13813
Maps.Pin Id xamarin/Xamarin.Forms#13813
Maps.Pin Clicked xamarin/Xamarin.Forms#13813

Xaml

Class Member to Remove Removed? PR
Xaml.Internals.SimpleValueTargetProvider .ctor(object[]) xamarin/Xamarin.Forms#13813
Xaml.Internals.SimpleValueTargetProvider .ctor(object[], object[]) xamarin/Xamarin.Forms#13813

UWP

Class Member to Remove Removed? PR
Platform.UAP.BoxViewRenderer
Platform.UAP.FormsSlider ThumbImage
Platform.UAP.RendererFactory

iOS

Class Member to Remove Removed? PR
Platform.iOS.RendererFactory
Platform.iOS.WebViewRenderer

Android

Class Member to Remove Removed? PR
Platform.Android.AndroidActivity
Platform.Android.PageExtensions CreateFragment

Android Renderer Constructors

Each renderer which existed as of 2.4 has an obsolete constructor which does not take a Context parameter.
 

Backward Compatibility

Any applications or libraries still using the obsolete properties or methods will have to update.

Difficulty : Low

Mostly this just means deleting methods and properties which already call through to other methods and properties. In a few cases we may also need to remove non-public members which are no longer used.

[Bug] Fix fundamental measuring and layout issues

Description

A Label in a grid that is contained in a StackLayout isn't measured correctly, with contents below the grid in the StackLayout overlapping the grid and label.

The original issue is here: xamarin/Xamarin.Forms#8797

Create a new template XF solution.
Replace the MainPage xml with a new MainPage.cs
Replace the code with the following and fix the namespace accordingly:
`
using System;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;

namespace LabelSizeTest
{
public class MainPage : ContentPage
{
public MainPage()
{
On().SetUseSafeArea(true);

    var grid = new Grid();
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
    grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });

    var label = new Label();
    label.LineBreakMode = LineBreakMode.WordWrap;
    label.Text = "This is a test teest test 2nd 3rd last";

    grid.Children.Add(label, 1, 0);

    var stack = new StackLayout()
    {
        VerticalOptions = LayoutOptions.FillAndExpand,
        HorizontalOptions = LayoutOptions.FillAndExpand,
    };

    stack.Children.Add(new BoxView()
    {
        BackgroundColor = Color.Blue,
        HeightRequest = 50
    });

    stack.Children.Add(grid);

    stack.Children.Add(new BoxView()
    {
        BackgroundColor = Color.Blue,
        HeightRequest = 50
    });

    Content = stack;
}

}
}
`
4. Run on the iPhone 11 Simulator.

Expected Behavior
Label should display correctly, with all the text visible.

Actual Behavior
Label is being partially obscured by the 2nd BoxView, the words 3rd and Last are replaced with the BoxView.

Basic Information
Version with issue:

Last known good version:

IDE: VS4Mac

Platform Target Frameworks:

iOS:
Nuget Packages: XF 4.2.0

Affected Devices: iOS and Android, as per the conversation in the original thread.

[Spec] drop AndExpand layout option

Description

The AndExpand suffix on some LayoutOptions is confusing at best, harmful and expensive at its worst.

It only make sense to have a single element (per axis) with AndExpand flag set, and only for a handful of layouts (StackLayout and Grid, mainly).

If a layout contains multiple expandable children per direction:

  • it should warn the user
  • all but the last one (in the direction) should be ignored

We could also optimize the layouts for these restrictions (reducing the measure for expand items, e.g.).

API

struct LayoutOptions,

Remove or [Obsolete]

class LayoutOptionsConverter

Remove or [Obsolete]

enum LayoutExpandFlag

Remove or [Obsolete]

class View

Properties and BindableProperties

Replace Vertical|HorizontalOptions[Property] by Vertical|HorizontalAlignment[Property]

API Description
public LayoutAlignment VerticalAlignment Gets or sets the verticalAlignemnt.
public LayoutAlignment HorizontalAlignment Gets or sets the verticalAlignemnt.
public static readonly BindableProperty VerticalAlignmentProperty bp for VerticalAlignemnt
public static readonly BindableProperty HorizontalAlignmentProperty bp for HorizontalAlignemnt

Add bool Vertical|HorizontalExpand[Property]. An attached BindableProperty would be more suited, as technically the Expand is only valid within some layouts, but the syntax would be harder for the user.

Scenarios

C# Example

var button = new Button();
button.ExpandVertically = true;
button.VerticalAlignment = LayoutAlignment.Center;

XAML Example

<Button x:Name="thing" ExpandVertically="true" VerticalAlignemnt="Center" />

CSS Example

Expansion is not supported in CSS

Backward Compatibility

Minimum API levels: N/A

Breaking changes: this require some modification in user XAML and code. The rule about a single expandable might produce different results than what we actually have.

Difficulty : medium

[Spec] Shadows

Shadows

Shadows create visual cues in the interface, which helps the human brain differentiate the UI element that the user sees. And, this the reason why actually mobile designers favor incorporating shadows in their designs.

shadows

API

The DropShadow class provides means of creating a configurable shadow that can be applied to a Layout.

Properties

  • Radius: The radius of the Gaussian blur used to generate the shadow.
  • Color: The color of the shadow.
  • Offset: Offset of the shadow relative to its Layout.
  • Opacity: The opacity of the shadow.
public class DropShadow : BindableObject
{
    public static readonly BindableProperty RadiusProperty = BindableProperty.Create(
        nameof(Radius), typeof(double), typeof(DropShadow), 10.0d);

    public double Radius
    {
        get => (double)GetValue(RadiusProperty);
        set => SetValue(RadiusProperty, value);
    }

    public static readonly BindableProperty ColorProperty = BindableProperty.Create(
        nameof(Color), typeof(Color), typeof(DropShadow), Color.Black);

    public Color Color
    {
        get => (Color)GetValue(ColorProperty);
        set => SetValue(ColorProperty, value);
    }    
    
    public static readonly BindableProperty OffsetProperty = BindableProperty.Create(
        nameof(Offset), typeof(Point), typeof(DropShadow), new Point(1, 1));

    public Point Offset
    {
        get => (Point)GetValue(OffsetProperty);
        set => SetValue(OffsetProperty, value);
    }
      
    public static readonly BindableProperty OpacityProperty = BindableProperty.Create(
        nameof(Opacity), typeof(double), typeof(DropShadow), 1.0d);

    public double Opacity
    {
        get => (double)GetValue(OpacityProperty);
        set => SetValue(OpacityProperty, value);
    }
}

Scenarios

Let's see an example using C #, XAML and CSS.

C# Example

var layout = new Grid();

var shadow = new DropShadow ();
shadow.Radius = 12;
shadow.Color = Color.Red;
shadow.Offset = new Point (12, 18);
shadow.Opacity = 0.75d;

layout.Shadow = shadow;

XAML Example

<Grid>
     <Grid.Shadow>
          <DropShadow
               Radius="12"
               Color="Red"
               Offset="12, 18"
               Opacity="0.75" />
     </Grid.Shadow>
</Grid>

CSS Example

box-shadow: 12px 18px 12px 12px red;

Backward Compatibility

We already have shadows in some of the Xamarin.Forms Layouts. Frame's HasShadow property would become deprecated (it could still be used, although the use of the Shadow property would be recommended).

Scope

In this Spec, we add shadows to the different Xamarin.Forms Layouts. Specific controls, such as a Label, do not fall within the scope (they could come later).

Difficulty : Medium

[Spec] Drop VS Compatibility with any versions of VS that don't support .NET 6

Remove CI and project properties that enable VS 2017 Compatibility

Currently we have a lot of CI and IL rewriting in place so that our current XF SDKs will run on VS 2017.

.NET 6 will definitely not run on VS 2017 so it won't be possible to build MAUI applications on Visual Studio 2017.

https://devblogs.microsoft.com/dotnet/introducing-net-5/

We intend to release .NET 5 in November 2020, with the first preview available in the first half of 2020. It will be supported with future updates to Visual Studio 2019, Visual Studio for Mac and Visual Studio Code.

The spirit of this Issue is that we aren't going to provide any support for MAUI on versions of VS that don't work with .NET6.

Backward Compatibility

This PR removes backwards compatibility with VS 2017. People using VS 2017 or VS Mac 5 won't be able to develop apps against Maui

Difficulty : Low

This is just deleting project settings that are only executed when running VS 2017 CI. It's a quick one

Remove infrastructure and IL rewriting that enables Xamarin.Forms to continue working with VS 2017

  • Remove all uses of Xamarin.Build.TypeRedirector Package References
  • Remove all the __XCODE11__ If defs and all of the code that's only compiled for XCode11
  • Remove the VS 2017 stages from the CI YAML files
  • Remove the code from the Xamarin.Forms.target file that's used to swap the iOS platform DLL based on if you're building with VS 2017
  • Search through all csproj/props/targets files for the property Use2017. Remove the property and keep all the VS 2019 paths

Question: XAML Flavor, Architecture & Roadmap

Summary

Is this project going to stick exclusively with the Xamarin Forms flavor of XAML? Is there any chance of adopting the "real" XAML from WPF/UWP? (TextBlock instead of Label, StackPanel instead of StackLayout, etc.) XAML Standard really should have been implemented by now.

If this is built on Xamarin Forms, what are the commitments in terms of bug fixes? Xamarin Forms is notoriously difficult to work with in an advanced way because of bugs and the complexity to fix them. The architecture is non-ideal for custom controls as well.

Honestly, I would like to use a Microsoft-backed cross-platform UI framework but Xamarin Forms is a poor choice for stability and the XAML differences from WPF/UWP. Other options, like the Uno Platform, are more attractive for these and other reasons.

Can you provide a detailed summary of this new framework architecture (is it just re-branded Xamarin Forms?) and a roadmap of where you are taking this in the future? I don't think this framework is what developers have been asking for but want to be sure before making decisions about current and future applications.

Cross platform UX for .NET 5

.NET Core does not support directly any desktop or mobile UI. It was designed and implemented without such a goal at least up to v2.1.0. Nevertheless, it is a feature which potentially may expand usage scenarios very significantly. It is one of the oldest and most voted up features on Visual Studio UserVoice as well.

Microsoft and Xamarin jointly own an XAML based UX code stack (WPF, UWP, Xamarin Forms, WinUI) which could form a basis for .NET 5 UX stack. Unfortunately, work on XAML-Standard has stalled despite that IMHO it would be a good place to make decision about UX in .NET 5.

Even more important Microsoft Fluent Design could be adopted in Core UX at least on Windows if not at least partially on other platforms. This would put .NET Core on bleeding edge of modern, universal xplat framework development. Currently I would prefer to run Microsoft Fluent API based app on my Mac. It was quite different at Windows Vista and 7 times (I work daily on both Mac and Windows).

One of the most important requirements would be a hardware support. Providing that MSFT and Xamarin currently use DirectX and OpenGL based technologies one should be able with significant investment create modern hardware accelerated graphics/media cross platform backend. This would as an additional benefit allow for providing modern graphics API as an alternative to outdated System.Drawing API resurrected for .NET Core v2.1.0

Related not only DotNet issues:

Port System.Xaml to .NET Core

Include WPF in the standard (XAML Standard)

Port Winforms to CoreFX

XAML Standard scope discussion

WinUI 3.0 roadmap - we need your input!

WPF, WindowsForms and WinUI (UWP XAML) are open source !!!

It's good time to start porting them to other platforms

Last updated 2019-05-20

[Spec] Slim Renderer Architecture

WARNING: this spec is still a WIP, we're still experimenting with this concept

Description

Slim renderers architecture benefits from multi-targetting and single-project features.

Example

EntryRenderer.cs

public partial class EntryRenderer {
   public static PropertyMapper<IView> ViewMapper = new PropertyMapper<IView> {
	
     // Add your own method to map to any property         
     [nameof(IView.BackgroundColor)] = MapBackgroundColor

   };
}

EntryRenderer.iOS.cs

// You don’t need to register a new renderer.
public partial class EntryRenderer
{
     // You know what method to call because you named it!
   public static void MapBackgroundColor (IViewRenderer renderer, IView view)
     {
        // You don’t need to call any base methods here or worry about order.
   
        // Every renderer is consistent; you know where the native view is.
          var nativeView = (NativeView)renderer.NativeView;
          var color = view.BackgroundColor;

          if (color != null) {

            // Phew! That was easy!	        
            nativeView.BackgroundColor = UIColor.FromRGB (204, 153, 255);
          }
     }
}

Standardization of renderers

All the default renderers will be ported to this architecture, for all platforms

Registration of renderers

The rendererRegistrar will exists on the dependency service and be accessed by serviceCollection.Get<IRendererRegistrar>(), allowing control to which renderer is associated to which control

Interfaces on renderers

Mapper concept

The property mapper is responsible for triggering actions in response property changes. A slim renderer itself does not subscribe to the property changes, but some declared actions are executed in response to changes.

The property mapper property of a control is public static and can be extended by user code.

The property mapper plays no role in the feedback loop (button clicked, text entered)

TODO: discuss what to use for mapper key. string or object ? It'd be nice to avoid string comparison in case when we can compare references (in case of BindableProperties)

How to use legacy custom renderers

How to use third-party controls depending on old renderers

How to complement existing renderers

The new extensibility model for this architecture is based on the property mapper. When you want to add support for a new property, it only requires mapping the new property. For the property to exists, subclassing the control is necessary, but subclassing the renderer is not.

Backward Compatibility

Wether we want to keep backward compatibility with existing custom renderers, or subclasses of old renderers will influence the architecture of this

Difficulty : very high

MVU might not be what you think it is

When I was reading the official announcement the other day, I was surprised what was presented there as MVU:

readonly State<int> count = 0;

[Body]
View body() => new StackLayout
{
    new Label("Welcome to .NET MAUI!"),
    new Button(
        () => $"You clicked {count} times.",
        () => count.Value ++)
    )
};

As far as I am concerned, this is not MVU. I already wrote down some thoughts on why I think so here.

Don Syme, who, as I understand, spent several months of 2018 on implementing MVU on top of Xamarin.Forms and building what later became Fabulous, is a bit more diplomatic, but the bottom line is the same.

So, what's my point?

  • I would love you to implement the real architectural pattern, no matter if in C# or F#. Reaching out to the people behind Fabulous could be a start here.
  • If you are not interersted in that but have a clear vision on building on top what is available today as the Comet library, then please consider using a more appropriate name for that "app model." Invent something new. Name it MSMVU. Whatever. But don't sell apples for oranges.

Cheers!

[Spec] Microsoft.Extensions.Hosting and/or Microsoft.Extensions.DependencyInjection

Bake the features of Microsoft.Extensions.Hosting into .NET MAUI

https://montemagno.com/add-asp-net-cores-dependency-injection-into-xamarin-apps-with-hostbuilder/

Utilize the Generic Host structure that's setup with .netcore 3.0 to initialize .NET MAUI applications.

This will provide users with a very Microsoft experience and will bring a lot of our code in line with ASP.NET core

Deeply root IServiceProvider into .NET MAUI

Replace all instances of Activator.CreateInstance(Type) with IServiceProvider.Get()

For example if we change this out on ElementTemplate

LoadTemplate = () => Activator.CreateInstance(type);

Then any DataTemplate specified via type will take advantage of being created via constructor injection.

Examples

Host.CreateDefaultBuilder()
	.ConfigureHostConfiguration(c =>
	{
		c.AddCommandLine(new string[] { $"ContentRoot={FileSystem.AppDataDirectory}" });
		c.AddJsonFile(fullConfig);
	})
	.ConfigureServices((c, x) =>
	{
		nativeConfigureServices(c, x);
		ConfigureServices(c, x);
	})
	.ConfigureLogging(l => l.AddConsole(o =>
	{
		o.DisableColors = true;
	}))
	.Build();        

static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
	if (ctx.HostingEnvironment.IsDevelopment())
	{
		var world = ctx.Configuration["Hello"];
	}

	services.AddHttpClient();
	services.AddTransient<IMainViewModel, MainViewModel>();
	services.AddTransient<MainPage>();
	services.AddSingleton<App>();
}

Shell Examples

Shell is already string based and just uses types to create everything so we can easily hook into DataTemplates and provide ServiceCollection extensions

static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
     services.RegisterRoute(typeof(MainPage));
     services.RegisterRoute(typeof(SecondPage));
}

If all the DataTemplates are wired up through the IServiceProvider users could specify Interfaces on DataTemplates

<ShellContent ContentTemplate="{DataTemplate view:MainPage}"/ShellContent>
<ShellContent ContentTemplate="{DataTemplate view:ISecondPage}"></ShellContent>

Baked in constructor injection

public class App
{
        public App()
        {
            InitializeComponent();
            MainPage = ServiceProvider.GetService<MainPage>();
        }
}
public partial class MainPage : ContentPage
{
   public MainPage(IMainViewModel viewModel)
   {
            InitializeComponent();
            BindingContext = viewModel;
   }
}

public class MainViewModel
{
        public MainViewModel(ILogger<MainViewModel> logger, IHttpClientFactory httpClientFactory)
        {
            var httpClient = httpClientFactory.CreateClient();
            logger.LogCritical("Always be logging!");
            Hello = "Hello from IoC";
        }
}

This will allow Shell to also have baked in Constructor Injection

Routing.RegisterRoute("MainPage", MainPage)

GotoAsync("MainPage") // this will use the ServiceProvider to create the type

All the ContentTemplates specified as part of Shell will be created via the IServiceProvider

    <ShellContent
        x:Name="login"
        ContentTemplate="{DataTemplate MainPage}"
        Route="login" />

Implementation Details to consider

Use Microsoft.Build to facilitate the startup pipeline

Pull in the host features to articulate a specific startup location where things are registered
https://montemagno.com/add-asp-net-cores-dependency-injection-into-xamarin-apps-with-hostbuilder/

This has the benefit of letting us tie into implementations of IoC containers that already work against asp.net core

Pros: This gives .NET developers a consistent experience.
Cons: Performance? Is this overkill for mobile?

DI Container options

Deprecate DependencyService in favor of Microsoft.Extensions.DependencyInjection

Xamarin.Forms currently has a very simple home grown dependency service that doesn't come with a lot of features. Growing the features of this service in the face of already available options doesn't make much sense. In order to align ourselves more appropriately with other Microsoft Platforms we can switch over to the container inside Microsoft.Extensions.DependencyInjection.

Automatic registration of the DependencyService will be tied to the new registrar. If the user has opted in for the registrar to do assembly scanning than this will trigger the DependencyService to scan for assembly level attributes

One of the caveats of using this container is that types can't be registered on the fly once the app has started. You can only register types as part of the startup process and then once the IServicePRovider is constructed that's it. Registration is closed for business

Pros: It's a full featured container
Cons: Performance?

Convert our DependencyService to use IServiceCollection as an internal container and have it implement IServiceProvider

This would allow us to use a very slimmed down no featured container if people just want the best performance. We could probably use this as a default and then people could opt in for the more featured one if they want.

public class DependencyService : IServiceProvider
{
}

public static ServiceCollectionExtensions
{
     public static DependencyService Create(this IServiceCollection);
}

Considerations

Is this overall useful for a new users app experience? Do we really want to add the overhead of understanding a the build host startup loop for new users? It would probably be useful to just have a default setup for all of this that just uses Init and then new users can just easily do what they need to without having to setup settings files/configureservices/etc..

Performance

In my tests limited tests it takes about 25 ms for the Microsoft Hosting bits to startup. We'll probably want to dive deeper into those 25 ms to see if we can get around it or if that cost is already part of a different startup cost we will already incur

Backward Compatibility

  • The current DependencyService scans for assembly level attributes which we will most likely shift to being opt in for .NET MAUI. The default will require you to register things via the Service Collection explicitly

Difficulty : Medium/Large

Existing work:
xamarin/Xamarin.Forms#8220

[Bug] Name clash with Maui Linux and MauiKit

Description

A multi-platform app UI toolkit with the name of maui was introduced by Microsoft on May 19th, 2020 according to https://devblogs.microsoft.com/dotnet/introducing-net-multi-platform-app-ui/:

MAUI simplifies the choices for .NET developers, providing a single stack that supports all modern workloads: Android, iOS, macOS, and Windows. The native features of each platform and UI control are within reach in a simple, cross-platform API for you to deliver no-compromise user experiences while sharing even more code than before.

There has been https://mauilinux.org/ for a long time:

Fast and easy to use, yet powerful for computer users of all levels, Maui is a part-rolling distribution based on KDE Neon/Ubuntu. Maui features its own managed repositories and backport channels and ships with the following software components and applications for day-to-day use

According to Wikipedia, Maui Linux has been around sine 2016.

Also, there has been MauiKit for a long time:

MauiKit, a free and modular front-end framework for developing fast and compelling user experiences

There is clearly a name clash.

Steps to Reproduce

  1. Visit https://mauilinux.org/ and https://fr.wikipedia.org/wiki/Maui_Linux
  2. Visit https://mauikit.org//
  3. Visit https://devblogs.microsoft.com/dotnet/introducing-net-multi-platform-app-ui/

Expected Behavior

Microsoft chooses names not already used in the Linux community.

Actual Behavior

Microsoft chooses names already used in the Linux community.

Screenshots

[Spec] Transitions

Transitions

Maui already has a complete animations API allowing you to create a live and fluid content on a page. However, what happens when navigating between pages?.

This spec defines a Maui transitions API. We have two types of well-differentiated transitions:

  • Traditional transitions: Traditionally transitions between different pages involved enter and exit transitions that animated entire view hierarchies independent to each other.
  • Shared element transitions: Many times, there are elements common to both activities and providing the ability to transition these shared elements separately emphasizes continuity between transitions and breaks activity boundaries as the user navigates the app.

shared_transitions

API

Traditional transitions

For the traditional transitions, we need a new enumeration with the supported transitions:

public enum NavigationTransitionType
{
    None,
    Fade,
    Flip,
    Scale,
    SlideFromLeft,
    SlideFromRight,
    SlideFromTop,
    SlideFromBottom,
    Turnstile
}

And, include new properties in the Page to allow page transitions using NavigationPage and Shell:

  • TransitionType: The transition effect used.
  • TransitionDuration: The transition duration in milliseconds.
public static readonly BindableProperty TransitionTypeProperty =
     BindableProperty.Create(nameof(TransitionType), typeof(NavigationTransitionType),   typeof(NavigationPage), PageTransitionType.None,
     BindingMode.TwoWay, null);

public NavigationTransitionType TransitionType
{
    get { return (NavigationTransitionType)GetValue(TransitionTypeProperty); }
    set { SetValue(TransitionTypeProperty, value); }
}

public static readonly BindableProperty TransitionDurationProperty =
     BindableProperty.Create(nameof(TransitionDuration), typeof(double), typeof(NavigationPage), 500d,
     BindingMode.TwoWay, null);

public double TransitionDuration
{
    get { return (double)GetValue(TransitionDurationProperty); }
    set { SetValue(TransitionDurationProperty, value); }
}

Shared element transitions

On the other hand, we need a way to allow the shared element transitions. The key is a way to "link" the same item available in two different pages.

We will have the TransitionTag attached property to the supported elements inherited from View:

public static readonly BindableProperty TransitionTagProperty =    
     BindableProperty.CreateAttached("TransitionTag", typeof(int), typeof(Transition), 0,
propertyChanged: OnPropertyChanged);

The use would be:

<Image Source="xamarin.jpg" TransitionTag="logo" WidthRequest="100" />

Tag the control to transition in the source page.

<Image Source="xamarin.jpg" TransitionTag="logo" WidthRequest="300" />

And tag the control to transition in the destination page.

Scenarios

Let's see some examples.

XAML Example

A sample using transitions between pages:

<ContentPage
     TransitionType=“SlideFromBottom”
     TransitionDuration="750" />

A sample using shared transitions elements:

Page 1:

<Image  
     Source="xamagon_preview.png"
     TransitionTag="xamagon"/>

Page 2:

<Image  
     Source="xamagon.png"
     TransitionTag="xamagon"/>

Notes

  • The TransitionTag in source and destination page needs to match in order to display the transition.
  • You can animate multiple views at once, but every TransitionTag in a page needs to be unique.

Difficulty : Medium

[Spec] Use explicit registration

Description

Use explicit registration, or avoid registration (like for slim renderers) instead of scanning all assemblies for assembly attributes for renderers, image handlers, stylepropery, dependency serivces, fonts, ...

As those need to be registered with extra information, the most portable way is to provide a service that you'd acquire on the IServiceCollection, then add the handlers to the service

No API provided at this time, as this covers multiple scenarios

Difficulty :low

[Enhancement] Configuration Api to act like aspsettings.json

Summary

In Xamarin Forms we had to relied on Xamarin essentials plugin for settings , moving forward with MAUI it would be nice if MAUI had the same approach as asp.net for example.

The settings file would be able to be transformed at time of publish base on the configuration manger public setting i.e Debug Or release. Their should be two json files created in the tooling.

Eg.
appsettings.json
appsettings.Development.json

Platforms Affected

ALL
IOS
ANDRIOD
MAC
ASP.NET
LINUX
TIZEN
WATCHOS

Access one can then access the config value from the file using the following. The system should be smart enough to no that the user is either in Debug Or Release Build.

Access to values can be as simple as

var test = Configuration.GetConnectionString("DefaultConnection");

But Could also have.

 bool test = Configuration.GetConnectionString("DefaultConnection").ToBollean();
 int32  test = Configuration.GetConnectionString("DefaultConnection").ToInt32();

API Changes

This should use the existing asp.net core configuration code where possible.
e.g.

{
"ConnectionStrings": {
"DefaultConnection": "Server=ServerBame;Database=DatabaseName;User Id=DB_5976_fitnessbud_user;Password=MyPassword;Trusted_Connection=True;MultipleActiveResultSets=true"

},
"JwtToken": {
"SecretKey": "mysecret should allow the value to be stored in a key chain",
"LiveIssuer": "http://api-url.net",
"expirationInMinutes": "2"
},
"EmailSettings": {
"MailServer": "mailserver name",
"MailPort": 25,
"SenderName": "",
"Sender": "",
"Password": ""
},

"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

[Spec] Shapes

Shapes

A Shape is a type of View that enables you to draw a shape to the screen.

But, hey, why Shapes?

Currently there are Views such as BoxView or Frame that allow us to create elements such as rectangles or ellipses but, there are many more complex shapes. Having a set of Shapes (lines, polygons, etc.) allows a greater number of possibilities when creating attractive and rich user interfaces.

shapes

Notice that in the design there are:

  • Dash Line
  • Circle (Ellipse)
  • Bubble (Path)
  • Nested Circles (Path)

API

Next, the Shapes API definition.

NOTE: This API definition is based on WPF Shapes API: https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/shapes-and-basic-drawing-in-wpf-overview

Shape

To render a Shape, must set the Fill property of the Shape to the Color you want. A Shape can also have a Stroke, which is a line that is drawn around the shape's perimeter. A Stroke also requires a Color that defines its appearance, and should have a non-zero value for StrokeThickness. StrokeThickness is a property that defines the perimeter's thickness around the shape edge.

public class Shape : View
{
    public static readonly BindableProperty FillProperty =
        BindableProperty.Create(nameof(Fill), typeof(Color), typeof(Shape), null);

    public static readonly BindableProperty StrokeProperty =
        BindableProperty.Create(nameof(Stroke), typeof(Color), typeof(Shape), null);

    public static readonly BindableProperty StrokeThicknessProperty =
        BindableProperty.Create(nameof(StrokeThickness), typeof(double), typeof(Shape), 1.0);

    public static readonly BindableProperty StrokeDashArrayProperty =
        BindableProperty.Create(nameof(StrokeDashArray), typeof(DoubleCollection), typeof(Shape), null,
            defaultValueCreator: bindable => new DoubleCollection());

    public static readonly BindableProperty StrokeDashOffsetProperty =
        BindableProperty.Create(nameof(StrokeDashOffset), typeof(double), typeof(Shape), 0.0);

    public static readonly BindableProperty AspectProperty =
        BindableProperty.Create(nameof(Aspect), typeof(Stretch), typeof(Shape), Stretch.None);

    public Color Fill
    {
        set { SetValue(FillProperty, value); }
        get { return (Color)GetValue(FillProperty); }
    }

    public Color Stroke
    {
        set { SetValue(StrokeProperty, value); }
        get { return (Color)GetValue(StrokeProperty); }
    }

    public double StrokeThickness
    {
        set { SetValue(StrokeThicknessProperty, value); }
        get { return (double)GetValue(StrokeThicknessProperty); }
    }

    public DoubleCollection StrokeDashArray
    {
        set { SetValue(StrokeDashArrayProperty, value); }
        get { return (DoubleCollection)GetValue(StrokeDashArrayProperty); }
    }

    public double StrokeDashOffset
    {
        set { SetValue(StrokeDashOffsetProperty, value); }
        get { return (double)GetValue(StrokeDashOffsetProperty); }
    }

    public Stretch Aspect
    {
        set { SetValue(AspectProperty, value); }
        get { return (Stretch)GetValue(AspectProperty); }
    }
}

Ellipse

An Ellipse is a shape with a curved perimeter. To create a basic Ellipse, specify a WidthRequest, HeightRequest, and a Color for the Fill.

public sealed class Ellipse : Shape
{

}

Example:

<Ellipse Fill="SteelBlue" HeightRequest="200" WidthRequest="200" />

Ellipse

Rectangle

A Rectangle is a four-sided shape with its opposite sides being equal. To create a basic Rectangle, specify a WidthRequest, a HeightRequest, and a Fill.
You can round the corners of a Rectangle. To create rounded corners, specify a value for the RadiusX and RadiusY properties. These properties specify the x-axis and y-axis of an ellipse that defines the curve of the corners.

public sealed class Rectangle : Shape
{
    public static readonly BindableProperty RadiusXProperty =
        BindableProperty.Create(nameof(RadiusX), typeof(double), typeof(Rectangle), 0.0);

    public static readonly BindableProperty RadiusYProperty =
        BindableProperty.Create(nameof(RadiusY), typeof(double), typeof(Rectangle), 0.0);

    public double RadiusX
    {
        set { SetValue(RadiusXProperty, value); }
        get { return (double)GetValue(RadiusXProperty); }
    }

    public double RadiusY
    {
        set { SetValue(RadiusYProperty, value); }
        get { return (double)GetValue(RadiusYProperty); }
    }
}

Example:

<Rectangle Fill="Blue" Width="200" Height="100" Stroke="Black" StrokeThickness="3" RadiusX="50" RadiusY="10" />

Rectangle

Polygon

A Polygon is a shape with a boundary defined by an arbitrary number of points. The boundary is created by connecting a line from one point to the next, with the last point connected to the first point. The Points property defines the collection of points that make up the boundary.

public sealed class Polygon : Shape
{
    public static readonly BindableProperty PointsProperty =
        BindableProperty.Create(nameof(Points), typeof(PointCollection), typeof(Polygon), null, defaultValueCreator: bindable => new PointCollection());

    public static readonly BindableProperty FillRuleProperty =
        BindableProperty.Create(nameof(FillRule), typeof(FillRule), typeof(Polygon), FillRule.EvenOdd);

    public PointCollection Points
    {
        set { SetValue(PointsProperty, value); }
        get { return (PointCollection)GetValue(PointsProperty); }
    }

    public FillRule FillRule
    {
        set { SetValue(FillRuleProperty, value); }
        get { return (FillRule)GetValue(FillRuleProperty); }
    }
}

The FillRule property specifies a "rule" which the composite shape uses to determine whether a given point is part of the geometry. There are two possible values for FillRule: EvenOdd and Nonzero.

Example:

<Polygon Fill="LightBlue" Points="10,200,60,140,130,140,180,200" />

Polygon

Line

A Line is simply a line drawn between two points in coordinate space. For a Line, make sure to specify values for the Stroke and StrokeThickness properties, because otherwise the Line won't render.

public sealed class Line : Shape
{
    public static readonly BindableProperty X1Property =
        BindableProperty.Create(nameof(X1), typeof(double), typeof(Line), 0.0);

    public static readonly BindableProperty Y1Property =
        BindableProperty.Create(nameof(Y1), typeof(double), typeof(Line), 0.0);

    public static readonly BindableProperty X2Property =
        BindableProperty.Create(nameof(X2), typeof(double), typeof(Line), 0.0);

    public static readonly BindableProperty Y2Property =
        BindableProperty.Create(nameof(Y2), typeof(double), typeof(Line), 0.0);

    public double X1
    {
        set { SetValue(X1Property, value); }
        get { return (double)GetValue(X1Property); }
    }

    public double Y1
    {
        set { SetValue(Y1Property, value); }
        get { return (double)GetValue(Y1Property); }
    }

    public double X2
    {
        set { SetValue(X2Property, value); }
        get { return (double)GetValue(X2Property); }
    }

    public double Y2
    {
        set { SetValue(Y2Property, value); }
        get { return (double)GetValue(Y2Property); }
    }
}

Example:

<Line Stroke="Red" X2="400"/>

Polyline

A Polyline is similar to a Polygon in that the boundary of the shape is defined by a set of points, except the last point in a Polyline is not connected to the first point.

public sealed class Polyline : Shape
{
    public static readonly BindableProperty PointsProperty =
        BindableProperty.Create(nameof(Points), typeof(PointCollection), typeof(Polyline), null, defaultValueCreator: bindable => new PointCollection());

    public static readonly BindableProperty FillRuleProperty =
        BindableProperty.Create(nameof(FillRule), typeof(FillRule), typeof(Polyline), FillRule.EvenOdd);

    public PointCollection Points
    {
        set { SetValue(PointsProperty, value); }
        get { return (PointCollection)GetValue(PointsProperty); }
    }

    public FillRule FillRule
    {
        set { SetValue(FillRuleProperty, value); }
        get { return (FillRule)GetValue(FillRuleProperty); }
    }
}

Example:

<Polyline Stroke="Black" StrokeThickness="4" Points="10,200,60,140,130,140,180,200" />

polyline

Path

A Path is the most versatile Shape because you can use it to define an arbitrary geometry. But with this versatility comes complexity. Define the geometry of a path with the Data property.

public sealed class Path : Shape
{
    public static readonly BindableProperty DataProperty =
            BindableProperty.Create(nameof(Data), typeof(Geometry), typeof(Path), null);

    public Geometry Data
    {
        set { SetValue(DataProperty, value); }
        get { return (Geometry)GetValue(DataProperty); }
    }
}

Geometry

Where Geometry provides a base class for objects that define geometric shapes.

public class Geometry : BindableObject
{

}

There will be:

  • LineGeometry
  • EllipseGeometry
  • RectangleGeometry
  • PathGeometry

LineGeometry

Represents the geometry of a line.

public class LineGeometry : Geometry
{
    public static readonly BindableProperty StartPointProperty =
        BindableProperty.Create(nameof(StartPoint), typeof(Point), typeof(LineGeometry), new Point());

    public static readonly BindableProperty EndPointProperty =
        BindableProperty.Create(nameof(EndPoint), typeof(Point), typeof(LineGeometry), new Point());

    public Point StartPoint
    {
        set { SetValue(StartPointProperty, value); }
        get { return (Point)GetValue(StartPointProperty); }
    }

    public Point EndPoint
    {
        set { SetValue(StartPointProperty, value); }
        get { return (Point)GetValue(StartPointProperty); }
    }
}

EllipseGeometry

Represents the geometry of a circle or ellipse.

public class EllipseGeometry : Geometry
{
    public static readonly BindableProperty CenterProperty =
        BindableProperty.Create(nameof(Center), typeof(Point), typeof(EllipseGeometry), new Point());

    public static readonly BindableProperty RadiusXProperty =
        BindableProperty.Create(nameof(RadiusX), typeof(double), typeof(EllipseGeometry), 0.0);

    public static readonly BindableProperty RadiusYProperty =
        BindableProperty.Create(nameof(RadiusY), typeof(double), typeof(EllipseGeometry), 0.0);

    public Point Center
    {
        set { SetValue(CenterProperty, value); }
        get { return (Point)GetValue(CenterProperty); }
    }

    public double RadiusX
    {
        set { SetValue(RadiusXProperty, value); }
        get { return (double)GetValue(RadiusXProperty); }
    }

    public double RadiusY
    {
        set { SetValue(RadiusYProperty, value); }
        get { return (double)GetValue(RadiusYProperty); }
    }
}

RectangleGeometry

Describes a two-dimensional rectangle.

public class RectangleGeometry : Geometry
{
    public static readonly BindableProperty RectangleProperty =
        BindableProperty.Create(nameof(Rectangle), typeof(Rectangle), typeof(RectangleGeometry), new Rectangle());

    public Rectangle Rectangle
    {
        set { SetValue(RectangleProperty, value); }
        get { return (Rectangle)GetValue(RectangleProperty); }
    }
}

PathGeometry

Represents a complex shape that may be composed of arcs, curves, ellipses, lines, and rectangles.

public sealed class PathGeometry : Geometry
{
    public PathGeometry()
    {
        Figures = new PathFigureCollection();
    }

    public static readonly BindableProperty FiguresProperty =
        BindableProperty.Create(nameof(Figures), typeof(PathFigureCollection), typeof(PathGeometry), null);

    public static readonly BindableProperty FillRuleProperty =
        BindableProperty.Create(nameof(FillRule), typeof(FillRule), typeof(PathGeometry), FillRule.EvenOdd);

    [TypeConverter(typeof(PathFigureCollectionConverter))]
    public PathFigureCollection Figures
    {
        set { SetValue(FiguresProperty, value); }
        get { return (PathFigureCollection)GetValue(FiguresProperty); }
    }

    public FillRule FillRule
    {
        set { SetValue(FillRuleProperty, value); }
        get { return (FillRule)GetValue(FillRuleProperty); }
    }
}

Example:

<Path Stroke="DarkGoldenRod" StrokeThickness="3" Data="M 100,200 C 100,25 400,350 400,175 H 280" />

path

Clip Views

All views (inherited from IView) have the Clip property of type Geometry.

clip-image

(In the previous sample, the header background image is clipped to achieve the diagonal effect).

The following example shows an Image without a defined clip region.

<Image 
     Source="waterlilies.jpg" 
     WidthRequest="200"
     HeightRequest="150" />

image

In the next example, an identical Image is created, except that it has a defined clip region.

<Image 
     Source="waterlilies.jpg" 
     WidthRequest="200" 
     HeightRequest="150">
     <Image.Clip>
     <EllipseGeometry
          RadiusX="100"
          RadiusY="75"
          Center="100, 75"/>
     </Image.Clip>
</Image>

clip-image

Applying Styles

We can customize the appearance of Shapes using styles. We can create the styles using XAML or CSS.

Using XAML:

<Style x:Key="MyRectangle" Target="Rectangle">
     <Setter Property="Fill" Value="Red"  />     
     <Setter Property="Stroke" Value="Black"  />
     <Setter Property="StrokeThickness" Value="2"  />
     <Setter Property="StrokeDashArray" Value="2"  />
</Style>

Using CSS:

#MyRectangle {
  fill: red;
  stroke: black;
  stroke-width: 2px;
  stroke-dasharray: 2;
}

Difficulty : Medium

[Spec] Essentials Dependency

Description

Take a dependency on the Essentials library. This will eliminate some of the overlap between this SDK and Essentials.

Overlapping APIs

These are APIs which are currently provided by both Forms and Essentials. Any additional functionality which Forms has will be ported to Essentials, and the Essentials APIs will be used.

App Theme

Light and Dark theme info.

Color Converters

Methods for converting color data to and from cross-platform Color.

Device Display Metrics

Informations such as screen size, density, and rotation.

Device Info

This includes information such as the device's Platform and Idiom.

Preferences/Properties

A simple persistent key/value store.

UI Thread Invocation

The Essentials implementation of UI thread access relies on a static MainThead class which is incompatible with multi-window applications on some platforms. We will need to maintain the current Forms Dispatcher pattern or modify Essentials to follow that pattern.

Backward Compatibility

For folks relying on functionality currently provided by Forms which will be dropped in favor of the Essentials version, this will be a breaking change.

Difficulty : Low

This will mostly be a matter of removing the Forms code which is duplicated in Essentials.

[Spec] TabView

TabView

We can have tabs using Shell. However, what happens if we want to have nested tabs within a specific section (Example: Grid)?, what if we want to fully customize each tab?. In these cases, we would need a Custom Renderer so far...

The TabView is a way to display a set of tabs and their respective content. TabView is useful for displaying several content while giving a user the capability to customize mostly everything.

tabview

NOTE: TabView is a cross-platform view that takes over when native tabs hit their limits, such as positioning with layouts, styling, and non-uniform styling like a raised button.

API

Next, a list with the TabView properties, events and visualstates.

Properties

TabView Properties

Property Type Description
TabItemsSource IEnumerable A collection used to generate the TabView's tab items.
TabViewItemDataTemplate DataTemplate the template the Tab View uses to generate tab items' header.
TabContentDataTemplate DataTemplate The template the Tab View uses to generate tab items' content.
IsCyclical Bool Enable or disable cyclical tabs navigation.
IsLazy Bool Enable or disable lazy tabs loading.
SelectedIndex Int Gets or sets the currently selected tab. Default is 0.
TabStripPlacement TabStripPlacement The TabStrip placement (top or bottom).
TabStripBackground Brush The TabStrip background.
TabIndicatorBrush Brush The TabIndicator background.
TabIndicatorHeight double The TabIndicator height.
TabIndicatorWidth double The TabIndicator width.
TabIndicatorPlacement TabIndicatorPlacement
TabIndicatorView View The TabIndicator content.
TabContentBackground Brush The tab content background.
TabContentHeight Double The tab content height.
TabStripHeight Double The TabStrip height.
TabContentHeight Double The tab content height.
HasTabStripShadow Bool Show or hide the TabStrip shadow effect.
IsTabTransitionEnabled Bool Enable or disable the transition between tabs.
IsSwipeEnabled Bool Enable or disable the swipe gesture.

TabViewItem Properties

Property Type Description
Text String The text of the tab.
TextColor Color The text color of the tab.
TextColorSelected Color The text color of the selected tab.
FontSize FontSize The font size used in the tab text.
FontSizeSelected FontSize The font size used in the selected tab.
FontFamily String The font family used in the tab.
FontFamilySelected String The font family used in the selected tab.
FontAttributes FontAttributes The font attributes used in the tab.
FontAttributesSelected FontAttributes The font attributes used in the selected tab.
Icon ImageSource The icon of the tab.
IconSelected ImageSource The ImageSource used as icon in the selected tab.
Content View The content of the tab. Is View, can use anything as content.
BadgeText Bool The badge text used in the tab.
BadgeTextColor Color The badge text color used in the tab.
BadgeTextColorSelected Color The badge text color used in the selected tab.
BadgeBackgroundColor Color The badge color used in the tab.
BadgeBackgroundColorSelected Color The badge color used in the selected tab.
IsSelected Bool a bool that indicate if the tab is selected or not.
TapCommand ICommand Command that is executed when the user tap a tab.
TapCommandParameter object The tap command parameter.

Events

TabView Events

Event Description
SelectionChanged Event that is raised when the selected tab changed.
Scrolled Event that is raised when is swiping between tabs.

TabViewItem Events

Event Description
TabTapped Event that is raised when the user tap a tab.

VisualStates

The Visual State Manager (VSM) provides a structured way to make visual changes to the user interface from code.
The VSM introduces the concept of visual states. TabView can have several different visual appearances depending on its underlying state.

TabView have four specific VisualStates:

  • CurrentTabVisualState
  • NextTabVisualState
  • PreviousTabVisualState
  • DefaultTabVisualState

Scenarios

Let's see some samples covering common scenarios.

Basic Tabs

Let's see a basic example:

<TabView 
    TabStripPlacement="Bottom"
    TabStripBackgroundColor="Blue">
    <TabViewItem
        Icon="triangle.png"
        Text="Tab 1">
        <Grid 
            BackgroundColor="Gray">
            <Label
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Text="TabContent1" />
        </Grid>
    </TabViewItem>
    <TabViewItem
        Icon="circle.png"
        Text="Tab 2">
        <Grid>
            <Label    
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Text="TabContent2" />
        </Grid>
    </TabViewItem>
</TabView>

basic-tabs

TabItemsSource

Using TabItemsSource (dynamic tabs):

<TabView
    TabItemsSource="{Binding Monkeys}"
    TabViewItemDataTemplate="{StaticResource TabViewItemTemplate}"
    TabContentDataTemplate="{StaticResource TabContentTemplate}" />

tabitemssource

Custom Tabs

The appearance of each tab can be customized:

<ControlTemplate
    x:Key="TabItemTemplate">
    <Grid>
    ...
    </Grid>
</ControlTemplate>

<TabView>
    <TabViewItem
        Text="Tab 1"
        ControlTemplate="{StaticResource TabItemTemplate}">
    </TabViewItem>
</TabView>

custom-tabs

Cyclical Tabs

Do you want to navigate between the tabs cyclically?

<TabView
    IsCyclical="True">
    ...
</TabView>

iscyclical

Lazy Loading

Lazy tab loading:

<TabView
    IsLazy="True">
    ...
</TabView>

lazy-tabs

Tab Transitions and TabViewItem animations

Can use Maui animations to customize the transition between each tab, animate the tab when appears or disappears, or even animate the badge when appears or disappears.

<TabView>
    <TabView.TabTransition>
        <local:CustomTabTransition />
    </TabView.TabTransition>
    <TabViewItem
        Text="Tab 1">      
            <TabViewItem.TabAnimation>
                <local:CustomTabViewItemAnimation />
            </TabViewItem.TabAnimation>
        <Grid 
            BackgroundColor="LawnGreen">
            <Label
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Text="TabContent1" />
        </Grid>
    </TabViewItem>
    ...
</TabView>

custom-tabs-animation

Using VisualStates

Can use different visual states to customize the current tab, the next tab, etc.

<Grid>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="TabViewStates">
            <VisualState x:Name="CurrentTab">
                <VisualState.Setters>
                    <Setter Property="Opacity" Value="1" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="PreviousTab">
                <VisualState.Setters>
                    <Setter Property="Opacity" Value="0.7" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="NextTab">
                <VisualState.Setters>
                    <Setter Property="Opacity" Value="0.7" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="DefaultTab">
                <VisualState.Setters>
                    <Setter Property="Opacity" Value="0.9" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Label Text="{Binding Index}" HorizontalOptions="Center" VerticalOptions="End" />
</Grid>

Create Tabs using C#

You can use XAML or C# to create the UI in Maui. Let's see how we would create tabs using C#.

var tabView = new Tabs
{
    TabStripPlacement = TabStripPlacement.Bottom,
    TabStripBackgroundColor = Color.Blue,
    TabStripHeight = 60,
    TabIndicatorColor = Color.Yellow,
    TabContentBackgroundColor = Color.Yellow
};

var tabViewItem1 = new TabViewItem
{
    Icon = "triangle.png",
    Text = "Tab 1",
    TextColor = Color.White,
    TextColorSelected = Color.Yellow,
};

var tabViewItem1Content = new Grid
{
    BackgroundColor = Color.Gray
};

var label1 = new Label
{
    HorizontalOptions = LayoutOptions.Center,
    VerticalOptions = LayoutOptions.Center,
    Text = "TabContent1"
};

tabViewItem1Content.Children.Add(label1);

tabViewItem1.Content = tabViewItem1Content;

tabView.TabItems.Add(tabViewItem1);

var tabViewItem2 = new TabViewItem
{
    Icon = "circle.png",
    Text = "Tab 2",
    TextColor = Color.White,
    TextColorSelected = Color.Yellow
};

var tabViewItem2Content = new Grid
{
    BackgroundColor = Color.OrangeRed
};

var label2 = new Label
{
    HorizontalOptions = LayoutOptions.Center,
    VerticalOptions = LayoutOptions.Center,
    Text = "TabContent2"
};

tabViewItem2Content.Children.Add(label2);

tabViewItem2.Content = tabViewItem2Content;

tabView.TabItems.Add(tabViewItem2);

Using Styles

Can customize the appearance of the tab content, tab strip, tab item, etc. using XAML styles or CSS.

Using XAML:

<Style
    x:Key="TabItemStyle"
    TargetType="TabViewItem">
    <Setter
        Property="FontSize"
        Value="12" />
    <Setter
        Property="TextColor"
        Value="#979797" />
</Style>

Using CSS:

.customTabItem {
    font-size: medium;
    text-color: red;
}

Difficulty : Medium

Possible name conflict with existing open-source project

The recent name change for Xamarin.Forms to MAUI might be a cause of confusion with an existing open-source project named Maui Project.

Maui Project has existed since 2018. This open-source project is also similar in scope in that it's a framework to develop cross-platform user interfaces.

There's a GitHub organization too https://github.com/mauikit. The code is mirrored from a Gitlab instance hosted by another broader open-source community, KDE. The Github organization predates this decision by Microsoft by about two years, with the first commits in the organization happening around April 29, 2018.

The name is also recursive for Maui Project, Multi-Adaptable User Interfaces.

I'm part of the group of developers that are involved in this project, and I would like to kindly ask for a way to resolve this possible naming confusion.

[Spec] Rounded Corners

Rounded Corners

Rounded Corners are a common visual requirement.

corners

API

We need to add an interface for defining what's required for a View to implement corner rounding (and provide CSS support):

interface IRoundedCorner
{
	CornerRadius CornerRadius { get; }
	void CornerRadiusChanged(CornerRadius oldValue, CornerRadius newValue);
}

The CornerRadius BindableProperty can be implemented in one place:

static class RoundedCorner
{
	public static readonly BindableProperty CornerRadiusProperty = 
	     BindableProperty.Create(nameof(CornerRadius), typeof(CornerRadius), typeof(IRoundedCorners));
}

The following Views are candidates for rounded corners:

  • BoxView
  • Button
  • Image
  • ImageButton
  • Layouts
  • ScrollView

Scenarios

C# Example

var grid = new Grid();
grid.CornerRadius = new CornerRadius(12, 0, 12, 6);

XAML Example

<Grid
     CornerRadius="12, 0, 12, 6">
</Grid>

Difficulty: Medium

Providing the interface is simple; individual implementations may vary in difficulty.

Third

[The feature]

Provide a concise description of the feature and the motivation for adding it to Xamarin.Forms

API

[ class ]

Properties

API Description
[name] Gets or sets [description].

Events

API Description
[name] [API documentation/description]

Scenarios

C# Example

var thing = new MyNewControl();
thing.BeAwesome = true;
thing.Color = Color.Cornsilk;

XAML Example

<MyNewControl x:Name="thing" BeAwesome="true" Color="Cornsilk" />

CSS Example

MyNewControl {
     color: Cornsilk;
}

Backward Compatibility

Minimum API levels?
Breaking changes?
Unsupported platforms?

Difficulty : [low/medium/high]

[Spec] Remove Android Pre-AppCompat

Description

Remove pre-AppCompat renderers and supporting classes from the Android Platform.

API Changes

Class to Remove AppCompat Replacement
FormsApplicationActivity FormsAppCompatActivity
Platform AppCompat.Platform
ButtonRenderer AppCompat.ButtonRenderer
CarouselPageRenderer AppCompat.CarouselPageRenderer
FrameRenderer AppCompat.FrameRenderer
MasterDetailRenderer AppCompat.MasterDetailPageRenderer
NavigationRenderer AppCompat.NavigationPageRenderer
PickerRenderer AppCompat.PickerRenderer
SwitchRenderer AppCompat.SwitchRenderer
TabbedRenderer AppCompat.TabbedPageRenderer

Backward Compatibility

This will be a breaking change for anyone still using the pre-AppCompat renderers. Those users will need to update their applications to use FormsAppCompatActivity and update any renderer customization to use the AppCompat renderers.

Difficulty : Low

This mostly entails deleting files.

[Spec] Views Status

Here you find a list of all controls with their (public) APIs and their status. If you find anything that needs an update, please feel free to do so.

Icon Description
⚠️ Pending
Underway
Done
💔 Never implemented in Forms for this platform

✅ ActivityIndicator

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Color ⚠️ ⚠️ ⚠️ ⚠️
IsRunning ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Button

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BackgroundColor ⚠️ ⚠️ ⚠️ ⚠️
BorderColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BorderRadius ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BorderWidth ⚠️ ⚠️ ⚠️ ⚠️
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Clicked ⚠️ ⚠️ ⚠️ ⚠️
Command ⚠️ ⚠️ ⚠️ ⚠️
CommandParameter ⚠️ ⚠️ ⚠️ ⚠️
ContentLayout ⚠️ ⚠️ ⚠️ ⚠️
CornerRadius ⚠️ ⚠️ ⚠️ ⚠️
Font ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ImageSource ⚠️ ⚠️ ⚠️ ⚠️
IsPressed ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Padding ⚠️ ⚠️ ⚠️ ⚠️
Pressed ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Released ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SendClicked ⚠️ ⚠️ ⚠️ ⚠️
SendPressed ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SendReleased ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Text ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️

⚠️ CarouselView

API Android iOS macOS 💔 WPF 💔 Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
ItemsSource 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ItemTemplate 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ItemsLayout 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
PeekAreaInsets 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
CurrentItem 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
CurrentItemChangedCommand 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
CurrentItemChangedCommandParameter 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsBounceEnabled 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsSwipeEnabled 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Position 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
PositionChangedCommand 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
PositionChangedCommandParameter 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
EmptyView 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
HorizontalScrollBarVisibility 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsDragging 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsScrollAnimated 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ItemsUpdatingScrollMode 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
VerticalScrollBarVisibility 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ CheckBox

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Color ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
CheckedChanged ⚠️ ⚠️ ⚠️ ⚠️
IsChecked ⚠️ ⚠️ ⚠️ ⚠️
IsCheckedVisualState ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ CollectionView

API Android iOS macOS 💔 WPF 💔 Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
ItemsSource 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ItemTemplate 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ItemsPanel 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ItemSizingStrategy 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SelectionMode 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SelectedItem 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SelectedItems 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SelectionChangedCommand 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SelectionChangedCommandParameter 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
EmptyView 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Scrolled 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ScrollTo 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Header 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
HeaderTemplate 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Footer 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
FooterTemplate 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsGrouped 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
GroupHeaderTemplate 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
GroupFooterTemplate 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ DatePicker

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Date ⚠️ ⚠️ ⚠️ ⚠️
DateSelected ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Format ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MaximumDate ⚠️ ⚠️ ⚠️ ⚠️
MinimumDate ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Editor

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
AutoSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Completed ⚠️ ⚠️ ⚠️ ⚠️
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️
IsReadOnly ⚠️ ⚠️ ⚠️ ⚠️
IsTextPredictionEnabled ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SendCompleted ⚠️ ⚠️ ⚠️ ⚠️
Text ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️
TextTransform ⚠️ ⚠️ ⚠️ ⚠️
MaxLength ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Entry

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
ClearButtonVisibility ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Completed ⚠️ ⚠️ ⚠️ ⚠️
CursorPosition ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️
HorizontalTextAlignment ⚠️ ⚠️ ⚠️ ⚠️
IsTextPredictionEnabled ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsPassword ⚠️ ⚠️ ⚠️ ⚠️
PlaceHolder ⚠️ ⚠️ ⚠️ ⚠️
PlaceHolderColor ⚠️ ⚠️ ⚠️ ⚠️
VerticalTextAlignment ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ReturnCommand ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ReturnCommandParameter ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ReturnType ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SelectionLength ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SendCompleted ⚠️ ⚠️ ⚠️ ⚠️
Text ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Expander

API Android iOS macOS ⏳ WPF 💔 Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CollapseAnimationEasing ⚠️ ⚠️ ⚠️ ⚠️
CollapseAnimationLength ⚠️ ⚠️ ⚠️ ⚠️
Command ⚠️ ⚠️ ⚠️ ⚠️
CommandParameter ⚠️ ⚠️ ⚠️ ⚠️
Content ⚠️ ⚠️ ⚠️ ⚠️
ContentTemplate ⚠️ ⚠️ ⚠️ ⚠️
ExpandAnimationEasing ⚠️ ⚠️ ⚠️ ⚠️
ExpandAnimationLength ⚠️ ⚠️ ⚠️ ⚠️
ForceUpdateSize ⚠️ ⚠️ ⚠️ ⚠️
ForceUpdateSizeCommand ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Header ⚠️ ⚠️ ⚠️ ⚠️
IsExpanded ⚠️ ⚠️ ⚠️ ⚠️
State ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Frame

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BorderColor ⚠️ ⚠️ ⚠️ ⚠️
CornerRadius ⚠️ ⚠️ ⚠️ ⚠️
HasShadow ⚠️ ⚠️ ⚠️ ⚠️

⚠️ IndicatorView

API Android iOS macOS 💔 WPF 💔 Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Count 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
HideSingle 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IndicatorColor 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IndicatorLayout 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IndicatorsShape 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IndicatorTemplate 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IndicatorSize 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
ItemsSource 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
MaximumVisible 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Position 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SelectedIndicatorColor 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Image

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Aspect ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsAnimationPlaying ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsLoading ⚠️ ⚠️ ⚠️ ⚠️
IsOpaque ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SetIsLoading ⚠️ ⚠️ ⚠️ ⚠️
Source ⚠️ ⚠️ ⚠️ ⚠️
Gif Support ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ ImageButton

API Android iOS macOS 💔 WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Aspect 💔 ⚠️ ⚠️ ⚠️ ⚠️
BorderColor 💔 ⚠️ ⚠️ ⚠️ ⚠️
BorderWidth 💔 ⚠️ ⚠️ ⚠️ ⚠️
Clicked 💔 ⚠️ ⚠️ ⚠️ ⚠️
Command 💔 ⚠️ ⚠️ ⚠️ ⚠️
CommandParameter 💔 ⚠️ ⚠️ ⚠️ ⚠️
CornerRadius 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsLoading 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsOpaque 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsPressed 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Padding 💔 ⚠️ ⚠️ ⚠️ ⚠️
Pressed 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
PropagateUpClicked 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
PropagateUpPressed 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
PropagateUpReleased 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
RaiseImageSourcePropertyChanged 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Released 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SendClicked 💔 ⚠️ ⚠️ ⚠️ ⚠️
SendPressed 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SendReleased 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SetIsLoading 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SetIsPressed 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Source 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Label

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️
FormattedText ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
GetChildElements ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
HorizontalTextAlignment ⚠️ ⚠️ ⚠️ ⚠️
LineBreakMode ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
LineHeight ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MaxLines ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Padding ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Text ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️
TextDecorations ⚠️ ⚠️ ⚠️ ⚠️
TextTransform ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
TextType ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
VerticalTextAlignment ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Map

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
HasScrollEnabled ⚠️ ⚠️ ⚠️ ⚠️
HasZoomEnabled ⚠️ ⚠️ ⚠️ ⚠️
IsShowingUser ⚠️ ⚠️ ⚠️ ⚠️
ItemsSource ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ItemTemplate ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ItemTemplateSelector ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
LastMoveToRegion ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MapClicked ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MapElements ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MapType ⚠️ ⚠️ ⚠️ ⚠️
MoveToLastRegionOnLayoutChange ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MoveToRegion ⚠️ ⚠️ ⚠️ ⚠️
Pins ⚠️ ⚠️ ⚠️ ⚠️
SendMapClicked ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SetVisibleRegion ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
TrafficEnabled ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
VisibleRegion ⚠️ ⚠️ ⚠️ ⚠️

⚠️ MediaElement

API Android iOS macOS 💔 WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Aspect ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
AutoPlay ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
BufferingProgress ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
CanSeek ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
CurrentState ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Duration ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
IsLooping ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
KeepScreenOn ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MediaEnded ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MediaFailed ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
MediaOpened ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Pause ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Play ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Position ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
PositionRequested ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SeekCompleted ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
SeekRequested ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
StateRequested ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ShowPlaybackControls ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Source ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Stop ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
VideoHeight ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
VideoWidth ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Volume ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
VolumeRequested ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Picker

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ItemDisplayBinding ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Items ⚠️ ⚠️ ⚠️ ⚠️
ItemsSource ⚠️ ⚠️ ⚠️ ⚠️
SelectedIndex ⚠️ ⚠️ ⚠️ ⚠️
SelectedIndexChanged ⚠️ ⚠️ ⚠️ ⚠️
SelectedItem ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️
Title ⚠️ ⚠️ ⚠️ ⚠️
TitleColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

✅ ProgressBar

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Progress ⚠️ ⚠️ ⚠️ ⚠️
ProgressColor ⚠️ ⚠️ ⚠️ ⚠️
ProgressTo ⚠️ ⚠️ ⚠️ ⚠️

⚠️ RadioButton

API Android iOS macOS WPF 💔 Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CheckedChanged 💔 ⚠️ ⚠️ ⚠️ ⚠️
GroupName 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsChecked 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsCheckedVisualState ⚠️ 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ RefreshView

API Android iOS macOS 💔 WPF 💔 Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Command 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
CommandParameter 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
IsRefreshing 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
RefreshColor 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Refreshing 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ ScrollView

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Content ⚠️ ⚠️ ⚠️ ⚠️
ContentSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
GetScrollPositionForElement ⚠️ ⚠️ ⚠️ ⚠️
HorizontalScrollBarVisibility ⚠️ ⚠️ ⚠️ ⚠️
LayoutAreaOverride ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Orientation ⚠️ ⚠️ ⚠️ ⚠️
SendScrollFinished ⚠️ ⚠️ ⚠️ ⚠️
SetScrolledPosition ⚠️ ⚠️ ⚠️ ⚠️
Scrolled ⚠️ ⚠️ ⚠️ ⚠️
ScrollToAsync ⚠️ ⚠️ ⚠️ ⚠️
ScrollToAsync overload(s) ⚠️ ⚠️ ⚠️ ⚠️
ScrollToRequested ⚠️ ⚠️ ⚠️ ⚠️
ScrollX ⚠️ ⚠️ ⚠️ ⚠️
ScrollY ⚠️ ⚠️ ⚠️ ⚠️
VerticalScrollBarVisibility ⚠️ ⚠️ ⚠️ ⚠️

⚠️ SearchBar

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CancelButtonColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
HorizontalTextAlignment ⚠️ ⚠️ ⚠️ ⚠️
Placeholder ⚠️ ⚠️ ⚠️ ⚠️
PlaceholderColor ⚠️ ⚠️ ⚠️ ⚠️
SearchButtonPressed ⚠️ ⚠️ ⚠️ ⚠️
SearchCommand ⚠️ ⚠️ ⚠️ ⚠️
SearchCommandParameter ⚠️ ⚠️ ⚠️ ⚠️
Text ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️
VerticalTextAlignment ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Slider

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
DragCompleted ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
DragCompletedCommand ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
DragStarted ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
DragStartedCommand ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Maximum ⚠️ ⚠️ ⚠️ ⚠️
MaximumTrackColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Minimum ⚠️ ⚠️ ⚠️ ⚠️
MinimumTrackColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ThumbColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ThumbImageSource ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Value ⚠️ ⚠️ ⚠️ ⚠️
ValueChanged ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Stepper

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Increment ⚠️ ⚠️ ⚠️ ⚠️
Maximum ⚠️ ⚠️ ⚠️ ⚠️
Minimum ⚠️ ⚠️ ⚠️ ⚠️
Value ⚠️ ⚠️ ⚠️ ⚠️
ValueChanged ⚠️ ⚠️ ⚠️ ⚠️
StepperPosition ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ SwipeView

API Android iOS macOS 💔 WPF 💔 Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BottomItems 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Close 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
CloseRequested 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
LeftItems 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
Open 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
OpenRequested 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
RightItems 💔 💔 ⚠️ ⚠️ ⚠️
SwipeChanging 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SwipeEnded 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
SwipeStarted 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️
TopItems 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Switch

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
IsToggled ⚠️ ⚠️ ⚠️ ⚠️
OnColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
ThumbColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ TimePicker

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CharacterSpacing ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontAttributes ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontFamily ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
FontSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Format ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Time ⚠️ ⚠️ ⚠️ ⚠️
TextColor ⚠️ ⚠️ ⚠️ ⚠️

⚠️ WebView

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
CanGoBack ⚠️ ⚠️ ⚠️ ⚠️
CanGoForward ⚠️ ⚠️ ⚠️ ⚠️
Cookies ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Eval ⚠️ ⚠️ ⚠️ ⚠️
EvalRequested ⚠️ ⚠️ ⚠️ ⚠️
EvaluateJavaScriptAsync ⚠️ ⚠️ ⚠️ ⚠️
EvaluateJavaScriptRequested ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
GoBack ⚠️ ⚠️ ⚠️ ⚠️
GoBackRequested ⚠️ ⚠️ ⚠️ ⚠️
GoForward ⚠️ ⚠️ ⚠️ ⚠️
GoForward Requested ⚠️ ⚠️ ⚠️ ⚠️
LoadHtml ⚠️ ⚠️ ⚠️ ⚠️
Navigated ⚠️ ⚠️ ⚠️ ⚠️
Navigating ⚠️ ⚠️ ⚠️ ⚠️
SendNavigated ⚠️ ⚠️ ⚠️ ⚠️
SendNavigating ⚠️ ⚠️ ⚠️ ⚠️
Source ⚠️ ⚠️ ⚠️ ⚠️
Reload ⚠️ ⚠️ ⚠️ ⚠️
ReloadRequested ⚠️ ⚠️ ⚠️ ⚠️

[Enhancement] Drop UIWebView WebRenderer

Summary

As we should all know by now, Apple has deprecated UIWebView for new apps effective April 2020 and existing apps effective December 2020. There is really no reason to keep deprecated references around in the code for a new framework that won't be released until late 2021.

API Changes

  • Remove class System.Maui.Platform.iOS.WebViewRenderer
  • Consider renaming WkWebViewRenderer to WebViewRenderer as the distinction is no longer necessary.

Intended Use Case

Remove any risk of Apple rejecting submission of apps using MAUI due to UIWebView references.

[Spec] Border

Border Options

Views can't easily be given borders without nesting them in frames or implementing custom renderers.

border-options

API

The following properties need to be added on the Border static class:

public static readonly BindableProperty BorderThicknessProperty =
     BindableProperty.Create(propertyName: nameof(BorderThickness),
	     returnType: typeof(Thickness), declaringType: typeof(View));
		
public static readonly BindableProperty BorderColorProperty =
	BindableProperty.Create(propertyName: nameof(BorderColor),
		returnType: typeof(Color), declaringType: typeof(View));

And on IBorder: BorderThickness

Thickness BorderThickness { get; }
Color BorderColor{ get; }

void OnBorderThicknessPropertyChanged(Thickness oldValue, Thickness newValue);
void OnBorderColorPropertyChanged(Color oldValue, Color newValue);

Renderers will frame the given view using the given border properties

The following Views should implement the IBorder interface:

  • Entry
  • Button
  • Frame
  • DatePicker
  • Picker
  • TimePicker

Scenarios

Let's see an example using C #, XAML and CSS.

C# Example

var entry = new Entry();
entry.BorderThickness = new Thickness (2);
entry.BorderColor = Color.Red;

XAML Example

<Entry
     BorderThickness="2"
     BorderColor="Red" />

CSS Example

.entry 
{  
    border-width: 2px;
    border-color: red;
}

Difficulty : Easy

[Edited] Is MVU-Style Coded-UI really necessary?

I think MAUI should stick with only one way of designing UI, that's: XAML

Blazor Syntex is okay, but MVU seems totally unnecessary mess to me. If it is to attract Flutter Devs, please, let them stay with Flutter; DO NOT destroy the beauty of XAML;

[Update]
image

[Spec] Features Status

Here you find a list of all the extra Features with their (public) APIs and their status. If you find anything that needs an update, please feel free to do so.

Icon Description
⚠️ Pending
Underway
Done
💔 Never implemented in Forms for this platform

⚠️ Accessibility

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Views ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Pages ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
TabIndex ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Animation

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
View ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Device

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BeginInvokeOnMainThread ⚠️ ⚠️ ⚠️ ⚠️
FlowDirection ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
GetNamedColor ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
GetNamedSize ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Idiom ⚠️ ⚠️ ⚠️ ⚠️
StartTimer ⚠️ ⚠️ ⚠️ ⚠️
Styles ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Gestures

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
ClickGestureRecognizer ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
PanGestureRecognizer ⚠️ ⚠️ ⚠️ ⚠️
PinchGestureRecognizer ⚠️ ⚠️ ⚠️ ⚠️
SwipeGestureRecognizer 💔 ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
TapGestureRecognizer ⚠️ ⚠️ ⚠️ ⚠️

⚠️ ImageHandlers

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
FileImageSource ⚠️ ⚠️ ⚠️ ⚠️
FontImageSource ⚠️ ⚠️ ⚠️ ⚠️
UrlImageSource ⚠️ ⚠️ ⚠️ ⚠️
StreamImageSource ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Interactivity

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Behavior ⚠️ ⚠️ ⚠️ ⚠️
Triggers ⚠️ ⚠️ ⚠️ ⚠️
VSM ⚠️ ⚠️ ⚠️ ⚠️

⚠️ FlowDirection

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
View ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Fonts

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Embedded Fonts ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
NamedFont ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Themes

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
AppTheme 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Shell

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
Basic Structure 💔 💔 ⚠️ ⚠️ ⚠️ ⚠️

⚠️ Styles

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
BodyStyle ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
CaptionStyle ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
DynamicStyle ⚠️ ⚠️ ⚠️ ⚠️
SubtitleStyle ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
TitleStyle ⚠️ ⚠️ ⚠️ ⚠️ ⚠️

⚠️ View Transforms

API Android iOS macOS WPF Android (MAUI) iOS (MAUI) macOS (MAUI) Windows (MAUI)
AnchorX ⚠️ ⚠️ ⚠️ ⚠️
AnchorY ⚠️ ⚠️ ⚠️ ⚠️
ClipToBounds ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
Opacity ⚠️ ⚠️ ⚠️ ⚠️
Scale ⚠️ ⚠️ ⚠️ ⚠️
ScaleX ⚠️ ⚠️ ⚠️ ⚠️
ScaleY ⚠️ ⚠️ ⚠️ ⚠️
Rotate ⚠️ ⚠️ ⚠️ ⚠️
TranslationX ⚠️ ⚠️ ⚠️ ⚠️
TranslationY ⚠️ ⚠️ ⚠️ ⚠️

WYSIWYG designer or drag and drop interface

Summary

Since it was out of scope there #43

All of you are right, but an option should also be available for beginners
to build apps crossplatform using something similar to windows forms drag
and drop, because ir makes things so much easier and manageable and
automatically, i think their should always be an option like this, in
modern day too, development shouldn't be only code code code it should be a
bit fun too.

[Spec] Fix Behaviour and Trigger inheritance

Description

The title says it all. Trigger and Behavior used to inherit from BindableObject, but are not bindable, and are actually shareable by instance. So that inheritance was a mistake, and it's misleading.

Backward Compatibility

This is a breaking change

Difficulty : low

[Spec] Remove Application.Properties

Description

Remove the Application.Properties key/value store from Forms in favor of the Essentials Preferences key/value store.

Forms currently provides a rudimentary key/value store using Application.Properties.

Essentials provides a similar but more robust option with Preferences. Additionally, Essentials includes a Secure Storage option.

We should remove the Forms Application.Properties feature in favor of the Essentials version. See also #19.

API

Remove:

System.Collections.Generic.IDictionary<string,object> Xamarin.Forms.Application.Properties { get; }

Xamarin.Forms.Internals.IDeserializer

Xamarin.Forms.Platform.UWP.WindowsSerializer

Xamarin.Forms.Platform.iOS.Deserializer

Xamarin.Forms.Platform.Android.Deserializer

Backward Compatibility

Users of the Properties feature will need to modify their code to use the Preferences feature.

Difficulty : Low

Mostly just deleting code - the Properties code, and also the various IDeserializer implementations.

[Spec] Brushes

Brushes

A gradient is the gradual blending from one color to another.

But, hey, why gradients?

Mobile design trends have changed rapidly in recent years, with some things disappearing for a while and then making a gradual comeback. That’s the case with gradients. Gradients are making a comeback.

gradients

API

Next, the Brushes API definition.

NOTE: This API definition is based on WPF Brushes API: https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/wpf-brushes-overview

Brush

Defines objects used to paint graphical objects. Classes that derive from Brush describe how the area is painted.

public abstract class Brush : BindableObject
{

}

SolidColorBrush

A SolidColorBrush paints an area with a solid Color.

public class SolidColorBrush : Brush
{
    public SolidColorBrush() { }

    public SolidColorBrush(Color color)
    {
        Color = color;
    }

    public static readonly BindableProperty ColorProperty = BindableProperty.Create(
        nameof(Color), typeof(Color), typeof(SolidColorBrush), Color.Default);

    public Color Color
    {
        get => (Color)GetValue(ColorProperty);
        set => SetValue(ColorProperty, value);
    }
}

solidcolorbrush

NOTE: For convenience, the Brushes class provides a set of commonly used SolidColorBrush objects, such as Blue and Yellow.

GradientBrush

A gradient brush paints an area with multiple colors that blend into each other along an axis.
The GradientBrush definition:

[ContentProperty(nameof(GradientStops))]
public class GradientBrush : Brush
{
    public static readonly BindableProperty GradientStopsProperty = BindableProperty.Create(
        nameof(GradientStops), typeof(IList<GradientStop>), typeof(GradientBrush), null);

    public IList<GradientStop> GradientStops
    {
        get => (IList<GradientStop>)GetValue(GradientStopsProperty);
        set => SetValue(GradientStopsProperty, value);
    }
}

The GradientStop is the basic building block of a gradient brush. A gradient stop specifies a Color at an Offset along the gradient axis.

public class GradientStop : BindableObject
{
    public static readonly BindableProperty ColorProperty = BindableProperty.Create(
        nameof(Color), typeof(Color), typeof(GradientStop), Color.White);

    public Color Color
    {
        get => (Color)GetValue(ColorProperty);
        set => SetValue(ColorProperty, value);
    }

    public static readonly BindableProperty OffsetProperty = BindableProperty.Create(
        nameof(Offset), typeof(float), typeof(GradientStop), 0f);

    public float Offset
    {
        get => (float)GetValue(OffsetProperty);
        set => SetValue(OffsetProperty, value);
    }
}

We will add a new property to IView to define the background using Brushes.

public static readonly BindableProperty BackgroundProperty = 
     BindableProperty.Create("Background", typeof(GradientBrush), typeof(VisualElement), default(GradientBrush));

This would allow gradients to be used as background in any control, although the BackgroundColor property would still exist (deprecated).

LinearGradientBrush

A LinearGradientBrush paints an area with a gradient that's defined along a line. This line is called the gradient axis.
You specify the gradient's colors and their locations along the gradient axis using GradientStop objects. By default, the gradient axis runs from the upper left corner to the lower right corner of the area that the brush paints, resulting in a diagonal shading.

LinearGradientBrush

public class LinearGradientBrush : GradientBrush
{
    public static readonly BindableProperty StartPointProperty = BindableProperty.Create(
        nameof(StartPoint), typeof(Point), typeof(LinearGradientBrush), default(Point));

    public Point StartPoint
    {
        get => (Point)GetValue(StartPointProperty);
        set => SetValue(StartPointProperty, value);
    }

    public static readonly BindableProperty EndPointProperty = BindableProperty.Create(
        nameof(EndPoint), typeof(Point), typeof(LinearGradientBrush), default(Point));

    public Point EndPoint
    {
        get => (Point)GetValue(EndPointProperty);
        set => SetValue(EndPointProperty, value);
    }
}

RadialGradientBrush

A radial gradient brush paints an area with a radial gradient that has a circle, along with a focal point, to define the gradient behavior. The focal point defines the center of the gradient and has default value 0.0.

RadialGradientBrush

public class RadialGradientBrush : GradientBrush
{
    public static readonly BindableProperty CenterProperty = BindableProperty.Create(
        nameof(Center), typeof(Point), typeof(RadialGradientBrush), default(Point));

    public Point Center
    {
        get => (Point)GetValue(CenterProperty);
        set => SetValue(CenterProperty, value);
    }

    public static readonly BindableProperty GradientOriginProperty = BindableProperty.Create(
        nameof(GradientOrigin), typeof(Point), typeof(RadialGradientBrush), default(Point));

    public Point GradientOrigin
    {
        get => (Point)GetValue(GradientOriginProperty);
        set => SetValue(GradientOriginProperty, value);
    }

    public static readonly BindableProperty RadiusXProperty = BindableProperty.Create(
        nameof(RadiusX), typeof(double), typeof(RadialGradientBrush), default(Point));

    public double RadiusX
    {
        get => (double)GetValue(RadiusXProperty);
        set => SetValue(RadiusXProperty, value);
    }

    public static readonly BindableProperty RadiusYProperty = BindableProperty.Create(
        nameof(RadiusY), typeof(double), typeof(RadialGradientBrush), default(Point));

    public double RadiusY
    {
        get => (double)GetValue(RadiusYProperty);
        set => SetValue(RadiusYProperty, value);
    }
}

Scenarios

Let's take a look at a simple sample:

XAML

<Grid>
    <Grid.Background>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="Yellow" Offset="0.0" />
            <GradientStop Color="Red" Offset="0.25" />
            <GradientStop Color="Blue" Offset="0.75" />
            <GradientStop Color="LimeGreen" Offset="1.0" />
        </LinearGradientBrush>
    </Grid.Background>
<Grid>

CSS

(see #7374)

#RootContainer{
    background: linear-gradient(45deg, rgba(218, 64, 244, 0.26) 0%, rgba(218, 64, 244, 0.26) 3%,rgba(184, 81, 207, 0.26) 3%, rgba(184, 81, 207, 0.26) 26%,rgba(149, 97, 169, 0.26) 26%, rgba(149, 97, 169, 0.26) 27%,rgba(115, 114, 132, 0.26) 27%, rgba(115, 114, 132, 0.26) 46%,rgba(80, 130, 94, 0.26) 46%, rgba(80, 130, 94, 0.26) 87%,rgba(46, 147, 57, 0.26) 87%, rgba(46, 147, 57, 0.26) 100%),linear-gradient(0deg, rgba(247, 80, 105, 0.26) 0%, rgba(247, 80, 105, 0.26) 1%,rgba(223, 84, 119, 0.26) 1%, rgba(223, 84, 119, 0.26) 11%,rgba(199, 88, 133, 0.26) 11%, rgba(199, 88, 133, 0.26) 46%,rgba(174, 91, 147, 0.26) 46%, rgba(174, 91, 147, 0.26) 54%,rgba(150, 95, 161, 0.26) 54%, rgba(150, 95, 161, 0.26) 73%,rgba(126, 99, 175, 0.26) 73%, rgba(126, 99, 175, 0.26) 100%),linear-gradient(90deg, rgb(74, 13, 231) 0%, rgb(74, 13, 231) 18%,rgb(96, 13, 230) 18%, rgb(96, 13, 230) 21%,rgb(119, 13, 229) 21%, rgb(119, 13, 229) 26%,rgb(141, 13, 228) 26%, rgb(141, 13, 228) 32%,rgb(163, 12, 226) 32%, rgb(163, 12, 226) 44%,rgb(185, 12, 225) 44%, rgb(185, 12, 225) 56%,rgb(208, 12, 224) 56%, rgb(208, 12, 224) 64%,rgb(230, 12, 223) 64%, rgb(230, 12, 223) 100%)
}

Scope

The Background property will be available in all the views.

Difficulty : Medium

100th :)

Summary

Can i stay here ? :)))))

[Bug] Naming problem - name is in use

Description

Could not find any open issue on this topic. Others are closed, but still not solved. That is why I open a new issue.

MAUI is a registered trademark in European Union. It is registered by Blue Systems which also employes KDE developers.

Here is a link about trademark status: https://euipo.europa.eu/eSearch/#details/trademarks/013410601

These news struck me like a lightning in early morning when I was drinking my coffee. This happening again? It was similar issue that Microsoft made in the past, I think it was GVfs (GNOME Virtual file system), and now this MAUI, which for the past idk maybe 6-8 years was a KDE project for front-end UI framework based on QQC2 and Kirigami. It is really nice project, free and open-source. How can someone just come and take the name of the project for some another project? Maybe my next project should be called .NET or Microsoft? I don't get it...

Solution to the problem would be simple: rename your project, as it is already registered trademark and these actions are illegal.

Oh, and one more thing. Stealing is bad. Microsoft should be ashamed of themselves.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.