AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.04k stars 2.25k forks source link

Improve XAML by removing noise #11906

Open ichthus1604 opened 1 year ago

ichthus1604 commented 1 year ago

Is your feature request related to a problem? Please describe.

I'm always frustrated when trying to explain XAML to a web developer.

Describe the solution you'd like

Remove all the unnecessary noise from XAML and make it friendlier to everyone.

Describe alternatives you've considered

None at the time.

Additional context

So, this is the XAML for an Avalonia Hello World:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="MyApp.Window1"
        Title="Window1">
  Welcome to Avalonia!
</Window>

That's a lot of noise to explain to somebody who has never used Avalonia nor WPF. It would be awesome if it was just:

<Window Title="Window1">
  Welcome to Avalonia!
</Window>

Since none of the other stuff is really required.

Also: it would be awesome if custom and user controls in an assembly where implicitly mapped to the root namespace instead of having to define a custom XAML namespace for them.

maxkatz6 commented 1 year ago

I have mixed feelings here.

I kinda agree that default xaml files can be improved. And I personally believe that a huge part of it - design-specific namespaces, can be eliminated altogether. But if we go in details...

xmlns and xmlns:x should really be implicit for every XAML file ever, since they're pretty much required.

XAML should still be a valid XML. Using nodes with namespaces (x:String...) without actually defining a namespace is not a valid XML. It won't be parsable by typical XML parser as well. xmlns="https://github.com/avaloniaui" specifically could be implicit. The problem is - Avalonia is not the only framework that uses XAML files, and xmlns is typically a way to differentiate that. Saying this, Avalonia switched to AXAML files by default, which is the same file format, but a different extension to avoid Visual Studio WPF bugs. So, possibly only for AXAML it can be implicit.

Now...xmlns:x is not really necessary in the default templates. And it ideally can be added by the IDE when any type is referenced from there.

xmlns:d and xmlns:mc are designer-specific concerns that don't really belong into production source code. The designer / previewer could handle this implicitly.

Agreed. But note, d:DesignWidth="800" d:DesignHeight="450" still needs to be specified. We can assume default values for the previewer and not force them, but there are lots of cases when developers actually want to test their controls/windows without any height/width set. How would they remove previewer size assumptions? But returning to my point about "eliminated design namespaces altogether" - it can be Design.Width="800" and Design.Height="450" properties that do not require any special namespace.

x:Class has 2 pieces of information:

I think this one can be safely assumed by the compiler when both XAML and C# files are of the same type. The question is if it can be a problem with existing use cases. I can't imagine one.

To summarize, in my imagination we should be able safely go down to:

<Window xmlns="https://github.com/avaloniaui"
        Design.Width="800" Design.Height="450"
        Title="Window1">
  Welcome to Avalonia!
</Window>

Which already is much better.

maxkatz6 commented 1 year ago

Personally, I believe that XAML can be improved, and it's still a better option than inventing a brand-new markup language.

rabbitism commented 1 year ago

Personally, I believe that XAML can be improved, and it's still a better option than inventing a brand-new markup language.

Maybe we can introduce a feature like global using in axaml.

maxkatz6 commented 1 year ago

@rabbitism it will be even less valid XML this way, though.

ichthus1604 commented 1 year ago

@maxkatz6 I think explicit XAML namespacing (at least for platform types) is fundamentally wrong. I understand the reasoning and design considerations behind it, but honestly at this point it looks to me as an unfortunate leftover from WPF compatibility.

Why is it {x:Type} and not just {Type}? Again, the only rationale for this seems to be WPF / other Microsoft stuff compat, which I as an Avalonia user don't value at all to be honest.

None of my Avalonia-based projects have anything to do with WPF. On the contrary, I'm writing greenfield software (primarily targeting WASM) using Avalonia right now. I'd rather see the platform advance into better usability and compete in the WASM space rather than staying forever tethered to legacy Microsoft stuff.

Also, even if WPF compat is a must (I understand Avalonia has a commercial offering specifically based on this), it could still support both idioms: keep {x:Type} for compatibility and enable {Type} as a way forward. This could even be toggled by an MSBuild option if needed (with the implicit default being the modern stuff, and the build flag required for legacy projects only)

If you remove the unnecessary differentiation of namespaces for platform types, then you no longer need xmlns:x, and if you implicitly define xmlns="https://github.com/avaloniaui", then you have already removed 90% of the noise in XAML for good, and XAML would still be valid XML because you're not using any unimported namespaces.

The only thing left for complete XAML happiness is to consider all assembly-local types as part of the root XAML namespace, so I don't have to xmlns:controls="using:MyApp.Controls" and then litter all my XAML with controls: everywhere. Not to mention that this escalates quite badly when you work with ViewModels and Views, which tipically belong to different namespaces, then you end up with

<Something
    xmlns="https://github.com/avaloniaui"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewmodels="using:MyApp.ViewModels"
    xmlns:someotherviewmodels="using:MyApp.SomeOtherViewModels"
    xmlns:views="using:MyApp.Views"
    xmlns:someotherviews="using:MyApp.SomeOtherViews">
    <DataTemplate DataType="{x:Type viewmodels:ViewModel1}">
        <views:View1/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type someotherviewmodels:ViewModel2}">
        <someotherviews:View2/>
    </DataTemplate>
</Something>

I think it is pretty obvious that this example above has very unfavorable noise to signal ratio. It gets even worse if you add ValueConverters to the equation.

It could just be:

<Something>
    <DataTemplate DataType="{Type ViewModel1}">
        <View1/>
    </DataTemplate>
    <DataTemplate DataType="{Type ViewModel2}">
        <View2/>
    </DataTemplate>
</Something>

Notice this is still 100% valid XML.

timunie commented 1 year ago

fyi: it's possible to define your own namespace and move all Views, ViewModels, Converter etc into that ns. Can also be the Avalonia one, then you can leave the prefix. See: https://docs.avaloniaui.net/guides/basics/introduction-to-xaml#create-a-common-namespace

byme8 commented 1 year ago

it will be even less valid XML this way,

What is the point of keeping it compatible with XML? No one in existence will use an XML parser to parse XAML.

Flithor commented 1 year ago

it will be even less valid XML this way,

What is the point of keeping it compatible with XML? No one in existence will use an XML parser to parse XAML.

Dude, XAML parser is parsing XAML by XML schema!

fforjan commented 1 year ago

To summarize, in my imagination we should be able safely go down to:

<Window xmlns="https://github.com/avaloniaui"
        Design.Width="800" Design.Height="450"
        Title="Window1">
  Welcome to Avalonia!
</Window>

Which already is much better.

Why do we need set a design size ? could we have an implicit size by default and only set the value if you need it ? And technically, I would have prefer to set something like 'lanscape' vs 'portait mode' or couple of other options instead of 'hard coded size' which always seems wrong anyway ?

byme8 commented 1 year ago

Dude, XAML parser is parsing XAML by XML schema!

To some degree, you are right. However, after the parsing, it does lots of magic on top of it. Without this magic, XAML is not XAML. So, effectively it is a completely new parser that is based on XML and for some reason limited by it. That why I am asking what the point to keep compatibility with XML.

byme8 commented 1 year ago

To summarize, in my imagination we should be able safely go down to:

<Window xmlns="https://github.com/avaloniaui"
        Design.Width="800" Design.Height="450"
        Title="Window1">
  Welcome to Avalonia!
</Window>

Which already is much better.

Why do we need set a design size ? could we have an implicit size by default and only set the value if you need it ? And technically, I would have prefer to set something like 'lanscape' vs 'portait mode' or couple of other options instead of 'hard coded size' which always seems wrong anyway ?

And potentially it can be done in the previewer itself. No need to define such values in XAML.

Symbai commented 1 year ago

Changing it would make it even more difficult for developers coming from WPF or MAUI or any other framework using XAML. And one of the reasons why Avalonia has been so successful is because for a typical C# developer, everything is familiar. Nothing is more frustrating then to read tons of documentation pages to get some basics done.

Instead of tampering with namespaces I'd actually enjoy if we have a better intellisense support. Because sometimes its missing and when its there, its not showing all the properties you can access. Its so awful comparing to WPF that I stopped using it and always look at / copy existing code when working on new pages. This would improve working with XAML a lot. Removing namespaces? Well I would put that into "nice to have" but that doesn't make MY life easier and also the life for users who start with Avalonia and then switch to WPF/MAUI or the other way around.

Another reason against the global mapping of namespaces is that for one page you use something like xmlns:vm="clr-namespace:YXZ.ViewModels" and for the other page you use xmlns:vm="clr-namespace:Abc123.ViewModels". This is the same situation why global usings on C# leads to cause conflicts if a name of a class exists both.

Improvements should make developing more easier and not just "looks better because less code". Sometimes more code is better. I can just think of the top level statement C# had introduced just to quickly provide a way to convert it back to old code + even added a checkbox when creating new C# projects if you want to use that or not. Because so many people hated it. Similar idea, similar solution, similar output.

ichthus1604 commented 1 year ago

Changing it would make it even more difficult for developers coming from WPF or MAUI or any other framework using XAML

I strongly disagree.

There is nothing "more difficult" in this:

<Window Title="Window1">
  Welcome to Avalonia!
</Window>

compared to this:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="MyApp.Window1"
        Title="Window1">
  Welcome to Avalonia!
</Window>

Quite the contrary, all that useless noise makes me really want to quit XAML and learn HTML and React just to be able to write markup similar to the first example.

Nothing is more frustrating then to read tons of documentation pages to get some basics done

Again, there is absolutely no need to read any documentation to understand my first example. Quite the contrary, people need to read tons of documentation just to be able to understand a simple Hello World app with all that amount of useless noise and unnecessary complexity in the markup. Let alone anything more complex.

users who start with Avalonia and then switch to WPF/MAUI

Sorry, WPF is legacy and MAUI is honestly unusable and full of bugs. I personally couldn't care less about any of that.

Also, as mentioned above, my proposal includes an MSBuildFlag (let's call it <UseLegacyXaml>True</UseLegacyXaml> if you want / need to use legacy XAML.

cause conflicts if a name of a class exists both

This does not happen in practice, and if it does the compiler should fail to build that specific case, which is 0.00001% compared to the 99.9999% of times I do not have any conflict but still I'm forced to explicitly specify everything manually, which again leads to useless noise.

Improvements should make developing more easier and not just "looks better because less code".

My proposal makes development substantially easier by avoiding unnecessary details such as namespaces that are totally not relevant when writing, nor maintaining code. This noise results in cognitive load, and cognitive load makes development substantially harder and more painful.

even added a checkbox

Yes. People are free to write legacy code with legacy idioms all they want. I personally want a way forward that doesn't force me to write code like it was 2006.

cesarchefinho commented 1 year ago

I agree.

the same "reducing noise" ocourred in html when browsers drop xhtml in favor to html5 that stripoed xml and merged svg and mathml in html

the same needs to be made in axaml

Sorien commented 1 year ago

Guys, look here https://github.com/AvaloniaUI/Avalonia/issues/2502 for better proposal

cesarchefinho commented 1 year ago

I dont like #2502

It is not better than this proposal, 2502 is flutter or qml or other strange thing but not xaml

this proposal maintain xaml and only simplifies markup, improving developper experience.

nnnpa31 commented 1 year ago

I don't think it's necessary to keep xaml in xml-based format, so I'm relatively supportive of #2502, but it's important to note that there's still a part of noise in the original proposal for #2502 that could be improved.

robloo commented 1 year ago

My comments:

  1. There could probably be some implicit namespaces... if XML supported it
  2. XAML should follow XML because the whole infrastructure has depended on that for almost 20 years
  3. We really need to be investigating new markup formats such as razor syntax to cover these types of modernizations. No one with existing XAML has complaints about this sort of thing. It just new devs coming on board.

So my vote is to leave things as they are for XAML and put effort into a more modern razor/blazor syntax that can be used side-by-side. https://github.com/AvaloniaUI/Avalonia/issues/2502#issuecomment-631845909

nnnpa31 commented 1 year ago

So my vote is to leave things as they are for XAML and put effort into a more modern razor/blazor syntax that can be used side-by-side. https://github.com/AvaloniaUI/Avalonia/issues/2502#issuecomment-631845909

Support this proposal, but it is easy to note that all similar proposals, including #11906 and #2502, eventually became unexplored and died just like #2502. Perhaps the Avalonia developers are working on this proposal, but I haven't seen anything about it from the official team in a long time.

timunie commented 1 year ago

Yeah, it's not that high on our todo list I guess. Overall, our API should be flexible enough to have a community lib that does provide another syntax. For example:

https://github.com/wieslawsoltes/NXUI https://github.com/fsprojects/Avalonia.FuncUI