Xamarin.forms: [Enhancement] Global XAML custom namespace schemas

Created on 8 Feb 2019  Â·  8Comments  Â·  Source: xamarin/Xamarin.Forms

Summary

If a developer has to declare a XAML namespace to import a control or library, it's likely that they must do this on multiple pages. Rather than having to write duplicate XMLNS imports on each page, this issue proposes a global XMLNS with a cascading effect, where an XMLNS declare in Application class XAML or in AssemblyInfo.cs automatically is available for use in pages referenced in that application.

API Changes

A developer can define their XMLNS in App.xaml, seen here:

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.App"
             xmlns:mycontrols="http://mycompany.com/schemas/controls">

</Application>

I then can use, without importing on each page, that XMLNS:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage  x:Class="MyApp.Views.NewItemPage">

    <ContentPage.Content>
        <StackLayout>
            <mycontrols:MyButton />
        </StackLayout>
    </ContentPage.Content>

</ContentPage>

Note: I'm not particularly attached to either method of defining a global XMLNS, just that those two places were the first two that came to mind.

Intended Use Case

This proposal would enable developers to write less boilerplate code and provide 'cleaner' XAML mark-up.

This is particularly useful for folks who utilize control libraries (such as Infragistics, Telerik, Syncfusion, GrapeCity, etc.), MVVM libraries (Prism, MVVMCross, etc.), or have a large set of shared components that are often reused across pages or projects.

enhancement âž•

Most helpful comment

The issue with this is starts to become a bit different than how the XML works

This makes it technically invalid XML
https://www.w3.org/TR/xml-names/#ns-using

The namespace prefix, unless it is xml or xmlns, MUST have been declared in a namespace declaration attribute in either the start-tag of the element where the prefix is used or in an ancestor element (i.e., an element in whose content the prefixed markup occurs).

I don't actually know what the practical impact of that is. I would guess it would make processing the XAML harder. I don't even know if the C# XML APIs let you inject a prefix definition which would presumably be required.

All 8 comments

@pierceboggan Interesting idea, I wonder if there are any side effects.

  1. Just to be sure I understand correctly, is there a small typo when using MyButton? should it be mycontrols:MyButton not controls:MyButton ?

  2. Does it mean we can also get rid of the following on the Page?

           xmlns="http://xamarin.com/schemas/2014/forms"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

@andreinitescu Fixed the typo, thanks! Yeah, in theory you should also be able to rid yourself of the other duplicate XMLNS as well.

I imagine that it's possible to get into a namespace conflict; if this happens, perhaps it's some sort of strategy like "page always wins" or something like that, just like how global styling can be overridden on at the page or control level.

OK, so if a Page redefines the prefix to anything else

xmlns:mycontrols="something_else"

the Page should use the new prefix.

Also, this inheritance works only from Application to Page.

The issue with this is starts to become a bit different than how the XML works (every XAML is a perfect XML)...

The issue with this is starts to become a bit different than how the XML works

This makes it technically invalid XML
https://www.w3.org/TR/xml-names/#ns-using

The namespace prefix, unless it is xml or xmlns, MUST have been declared in a namespace declaration attribute in either the start-tag of the element where the prefix is used or in an ancestor element (i.e., an element in whose content the prefixed markup occurs).

I don't actually know what the practical impact of that is. I would guess it would make processing the XAML harder. I don't even know if the C# XML APIs let you inject a prefix definition which would presumably be required.

@GalaxiaGuy yeah any tooling which works on XAML which uses a XML pre-processor would have to pre-pre-process the XML to include these namespace definitions before trying to read it as a XML doc.

I do this for UWP with XAML Studio so that it looks up known prefixes from a table to insert into the root tag if you paste in some random XAML, but it's all RegEx and string manipulation before I can pass it into an XDocument to do further manipulation magic.

WPF had the XmlnsDefinition option see a blog here. Something like that seems like a better route as long as the XAML processor can still function and things like LoadFromXaml can be given hints.

I like the goal... but I think this opens up a can of worms that isn't worth dealing with. As was previously pointed out this would actually create invalid XML. You also have to account for the very real possibility that the XAML file may reside in an entirely different assembly from the App that defines this namespace... which I think creates a lot of problems by itself... Assuming for a moment that we somehow make this work... what if your intent of the foo namespace was to point at the clr namespace Foo... but the consuming app that references this XAML file defined the foo namespace as the clr namespace Foo.Bar?

Ultimately I think the best thing for simplifying XML Namespaces was the opening of the XmlnsDefinitionAttribute. This will really reduce how many you need to add, not to mention make it easier...

<ContentPage xmlns:prism="http://prismlibrary.com"
             xmlns:sf="http://syncfusion.com"
             xmlns:tk="http://telerik.com">

this approach which is already 3.5 also makes it even easier considering the fact that AFAIK there is nothing stopping a 3rd party from adding their API's to the default namespace that Xamarin Forms uses...

You should be able to do this already with the new xmlns definition attribute. I've been doing this for years in wpf by just using the same definition as the default controls were using:
https://github.com/dotMorten/UniversalWPF/blob/bffe3e6c2cd1aaadc03cb9ff8acabe99812a7aca/src/UniversalWPF.RelativePanel/Properties/AssemblyInfo.cs#L29

@pierceboggan thanks for this PR. We had that discussion, if I remember well. This makes invalid XML and invalid XAML. We could (probably) deal with that, but this will break all the tooling existing around XAML files, and we don't want to break that.

also, multiple Application can exists...

Was this page helpful?
0 / 5 - 0 ratings