microsoft / xaml-standard

XAML Standard : a set of principles that drive XAML dialect alignment
Other
804 stars 50 forks source link

Ensure XAML and code are equivalent #58

Open skendrot opened 7 years ago

skendrot commented 7 years ago

This probably goes without saying, but XAML definitions need to match code behind definitions. So the following XAML and C# should both work

XAML

<StackPanel>
    <TextBlock Text="Name"/>
    <TextBlock Text="Shawn"/>
</StackPanel>

C# code behind

var panel = new StackPanel();
panel.Children.Add(new TextBlock { Text = "Name" });
panel.Children.Add(new TextBlock { Text = "Shawn" });

This shouldn't matter what platform you are running on.

pedrolamas commented 7 years ago

I wouldn't expect anything else than this... am I missing something?

skendrot commented 7 years ago

I want to make sure this isn't a "markup standard". But more the controls/code that you use within markup

dotMorten commented 7 years ago

Rumor has it that Xamarin.Forms will only be aliasing the controls and properties. Example, you might write this in XAML:

<TextBlock  x:Name="text" Visibility="Collapsed" />

However in code-behind you will see that text is of type Label, and text.IsVisible is false, and no Visibility property even exists on the type. If this is indeed true, it introduces huge unpredictability between how XAML and code relates, increasing not reducing the learning curve of the developers. While I can see the short-term thinking of doing it this way, I think it would be detrimental to the XAML standard if this is the behavior that's going to be used.

Now I don't expect the full object model hiarchy (ie inherit from FrameworkElement etc), but I do expect that there's a control type named "TextBlock" and it has a Visibility property (inherited or not).

pedrolamas commented 7 years ago

That would make this a half-baked half-standard in my book...

If that is the case, this is just a XAML abstraction of the existing UWP/Xamarin XAML, but from the code side, we would still have to use #if or other weird stuff...

In my mind, XAML has always been a 1:1 between the XML code and the C#/C++ code, so please, please: make this a FULL standard!!

MovGP0 commented 7 years ago

„XAML definitions need to match code behind definitions“

In a matter of fact, they do exactly that!

XAML itself is nothing more that a method to write .NET objects. In Xamarin those .NET objects are mapped to handlers who in turn render the native controls and map the properties onto this controls.

So don't confuse XAML declarations with native controls.

dotMorten commented 7 years ago

@MovGP0 The fact that there are renderers that convert these into native controls is all internal plumbing and has nothing to do with the code-behind that I actually get to write directly against.

skendrot commented 7 years ago

@MovGP0 The point here is that if a control is a Textblock in markup, that is should be a Textblock in code as well. In Xamarin.Forms, a "Textblock" is called a label. So I shouldn't have a Textblock in markup and a Label in code.

Note that i stated "markup" and not XAML. XAML is both markup and code

dotMorten commented 7 years ago

Note that I stated "markup" and not XAML. XAML is both markup and code

What? The "M" literally stands for "Markup".

birbilis commented 7 years ago

the Xamarin guy we all know (I always misspell his name) was saying in Build video that the UWP version for XAML Standard will be straight to the metal, which the Xamarin one will have an intermediate layer (guess wrapper objects). So I guess code behind will work as you expect. It's just that runtime debugging UI tooling might see some children underneath the XAML standard objects - maybe one could tell the tooling to not go that deep

mrlacey commented 7 years ago

Again, I don't see how the markup and code couldn't be equivalent.

@dotMorten Talking with Xamarin folks, I was told that X.F won't break backward compatibility so there will be some shims/adapters/translations going on. How this ends up being exposed in tooling is probably still undecided.

insinfo commented 7 years ago

I support and agree with you, plus some specific cases there will be differences and this is normal, are implementation details.

[admin (crutkas) removed link spam]

birbilis commented 7 years ago

Please don't crosslink items that are not directly related to a discussion, one sees to many links between discussion items like that

dotMorten commented 7 years ago

@mrlacey There's several ways you could "Fix" Xamarin.Forms, none of them are great as they all have each their cons:

  1. Do-over. Make breaking changes and refactor it all to match UWP.
  2. On-the-fly translate XAML. so a TextBlock in XAML becomes Label in codebehind, and properties become similarly translated.
  3. Replace controls. Ie Create a new control TextBlock and deprecate Label. Similar add Visibility property to base classes and deprecate IsVisible.

I realize Microsoft doesn't want to do (1). While it's probably the "right" thing to do from a purist point of view, it would cause a lot of friction for existing users, and it's not generally something Microsoft likes to do. (2) would be technically simple and safe to do, but it would be a huge detriment to the understanding and predictability of XAML and how it relates to its code-behind (also see this comment). (3) is the option I vote for: It gets a "proper" predictable object model, yet avoid breaking changes.

Also I think there is something to be said for code-behind being considered in the standard. While I get this is strictly trying to define the markup part, the standard doesn't really help us solve the mess Xamarin.Forms already creates. An example is that people so often use a click handler in XAML to switch to code-behind, and toggle Visibility of another control. We need that event handler to look similar, and be able to rely on the property to set is called Visibility on all platforms, and not IsVisible on XF. I can only imagine the giant mess it would be to try and explain this to the users of such a framework.

Now I don't really expect/need a full object-model re-architechture. The base class really doesn't need to be called the same, or where each property lives in the hierarchy since it doesn't matter much for code reusability. What matters are that they are there on the concrete classes we expect.

Of course all of this is just my opinion. I base it on the main problem I see with my team and customers starting with WPF/UWP/XF: They really struggle with the class and property name differences that XF has added. Issues I don't see when they move from WPF to UWP (the issue there is more lack of features but they get up and going quick). Fixing the naming issues would be the number 1 priority, and Option 1 and 3 could do that. Option 2 is a complete no-go as it only half-fixes the problem. Now I understand the historic reasons why XF is different, but let's be honest: If XF had copied the WPF classes much closer to begin with, I doubt we would even see XAML Standard be a thing today, and we'd probably only be asking more for feature parity, over fixing all these silly API differences.

birbilis commented 7 years ago

Why couldn't a TextBlock extend a Label there? Btw a Label control is/should be different than TextBlock. Should have a property tell which control it is assigned to for accessibility reasons

birbilis commented 7 years ago

Btw, if Xamarin Label has that extra property, it could extend Textblock instead and introduce at both uwp and xforms

monkeynoises commented 7 years ago

I'd vote for 3 too. I'd even argue, where a "name" has already been used.....instead of trying to find an alternative name...and using obscure "names" just to avoid clashes......just use a common namespace to distinguish them e.g. classic: and stan: ....so it would allow classic:Label, and stan:Label to be used at the same time (if needed). You could have something that automatically refactored/remapped "old" control usage to the "standard" ones if you weren't using classic specific only functionality.

The "names" of the controls should be naturally identifiable...based on the heritages of DOS->WIN32->WPF->SilverLight->WP7 (which is where XAML is originally from).....should the "target" native controls...really be influencing the names...as they vary among different platforms?

mrlacey commented 7 years ago

Yes, I think 3 is the way to go. I expect that we'll see lots of things supported and marked as deprecated as the standard becomes adopted but don't expect anything that would force a break with backward compatibility to get in.

insinfo commented 7 years ago

Undoubtedly a smooth transition is the best way to go at the moment, adding controls without removing the old ones, making semiannual and annual quarterly increments, with a different degree of change, is that most of the APIs do today like Android, IOS and others

nigel-sampson commented 7 years ago

Agree with @dotMorten in that the standard should be the same in the code behind as well.

Keeping Xaml as a serialization format makes it easier to reason about when reviewing and makes cross platform code that works with the UI easier to write.

You can get a little way there with type aliases in the code such as:

using UIElement = global::Xamarin.Forms.Element;
using FrameworkElement = global::Xamarin.Forms.VisualElement;
using DependencyProperty = global::Xamarin.Forms.BindableProperty;
using DependencyObject = global::Xamarin.Forms.BindableObject;
using ContentControl = global::Xamarin.Forms.ContentView;

but this only works when they have a standard API surface. As soon as you need to deal with the DataContext then we need to #if XAMARIN_FORMS etc.

birbilis commented 7 years ago

I remember there was some trouble (at least in Silverlight) when trying to convert XAML to equivalent code-behind (to avoid having the XAML at ancestor controls, since when trying to make an SL game also work with WPF the UserControls couldn't extend from others that were XAML-file based). There were some related StackOverflow questions too.

But can't remember what it was that didn't map in a straightforward way from declarative XAML to imperative C# commands. Probably was something with Styles or Bindings, there wasn't some publicly exposed property or method I think. Not sure if that was a Silverlight-only issue (was trying to make the XAML+code work via file sharing at both WPF and Silverlight).

Believe one could make a tool to convert XAML to commands (and vice-versa if those commands are kept in the same syntax that the tool understands [no if/loops etc. added that is]). Bit like compiling XAML, but into explicit C# commands (compilable source code), not into declarative binary (BAML - correct me if BAML wasn't declarative but imperative instead)