Forum Xamarin.Forms

Inclusion of APIs and attributes to aid in serializing objects to XAML.

michaeledmichaeled USMember
edited January 2017 in Xamarin.Forms

Summary

Inclusion of APIs and attributes to aid in serializing objects to XAML.

API Changes

I'm including two API changes that could be posted seperately, but likely wouldn't be released without the other.
These changes include decorating properties that could be serialized to XAML with the DefaultValueAttribute and implementing TypeConverter.ConvertTo methods.

TypeConverter

TypeConverter defines four members that are relevant for converting to and from strings for XAML processing purposes:

  • CanConvertTo
  • CanConvertFrom
  • ConvertTo
  • ConvertFrom

Currently only the "from" methods are implemented.

Using PointTypeConverter as an example:


For brevity, I didn't include the invariant methods.

DefaultValueAttribute

Decorating properties with the DefaultValueAttribute would aid in generating human-readable XAML output.

Using Xamarin.Forms.Frame as an example, the following was generated using a fork of Mono's System.Xaml:

<Frame AnchorX="0.5" AnchorY="0.5" BackgroundColor="Default" HasShadow="True" HeightRequest="-1" HorizontalOptions="Fill" InputTransparent="False" IsClippedToBounds="False" IsEnabled="True" IsVisible="True" Margin="0" MinimumHeightRequest="-1" MinimumWidthRequest="-1" Opacity="1" OutlineColor="Default" Padding="20" Rotation="0" RotationX="0" RotationY="0" Scale="1" TranslationX="0" TranslationY="0" VerticalOptions="Fill" WidthRequest="-1" AutomationId="{x:Null}" BindingContext="{x:Null}" ClassId="{x:Null}" ControlTemplate="{x:Null}" Parent="{x:Null}" Resources="{x:Null}" Style="{x:Null}" StyleId="{x:Null}" StyleClass="{x:Null}" Content="{x:Null}" />
public class Frame
{
    // Current API
    public bool HasShadow {}

    // Proposed API
    [DefaultValue(true)]
    public bool HasShadow {}
}

Assuming the DefaultValueAttribute was applied on all required properties, the following would be the expected output when serializing the Frame object to XAML once again:

<Frame></Frame>

Intended Use Case

The intended use case for these inclusions would be for visual designers and code generators.
In the past, I've had modest success serializing a visual graph to XAML.
Along the way I created a handful of type converters that may be of interest when further investigating this request.

https://github.com/michaeled/Portable.Xaml/tree/develop/src/XamarinFormsTypeConverters

Tagged:

Open · Last Updated

Posts

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    How is this done in different toolkits ?

  • michaeledmichaeled USMember
    edited January 2017

    The use-case I'm interested in is serializing the VisualElement object tree of a design surface to XAML. An example of this would be the design surface of Microsoft's Blend. Blend uses types mentioned in the original post, in addition to others, to accomplish this goal. Other types used during the XAML save path are ValueSerializer, DesignerSerializationVisibility, etc.

    The objects on the design surface are instantiated Xamarin.Forms VisualElements, so that says a bit about how the serialization occurs. I'm not informed on the workings of Xamarin.Forms.Init(), but today you cannot serialize a VisualElement until its invoked. I tested this using Mono's System.Xaml.

    In addition, which XamlWriter implementation Xamarin.Forms would rely upon isn't clear to me.

    Microsoft's System.Xaml isn't open source, and it relies on types in the System.ComponentModel namespace like DefaultValueAttribute and TypeConverter. Xamarin.Forms has its own TypeConverter implementation not recognized by Microsoft's or Mono's System.Xaml implementation.

    If I recall correctly, Mono's System.Xaml doesn't support all the XAML language features in its save path. I don't believe it can serialize a Dictionary object, but that would need to be validated.

    In the past, I've serialized Xamarin.Forms objects using Portable.Xaml. I implemented the needed TypeConverters by creating classes that extend from Portable.Xaml.TypeConverter. For a given type converter, it would delegate calls to the required Xamarin.Forms TypeConverter.ConvertFrom methods. The ConvertTo methods were implemented in the Portable.Xaml.TypeConverter classes. I modified XamlWriter to use these new TypeConverters instead of the Xamarin.Forms implementation whenever it encountered them during processing.

    I singled-out type converters in my original post because they provided me the most value during my attempts to save a Xamarin.Forms object tree to XAML.

    Additionally, some interesting questions arise when embedding native platform views in your project.

    There are quite a bit of challenges specific to making a design tool that would likely be out of scope for this request. A round-trip loading of a XAML file, creating a XAML node-stream, and saving that stream back to XAML is lossy.
    It introduces its own set of unique problems. I would think those challenges are out-of-scope.

    Now that the Xamarin.Forms macOS port is stabilizing, the time maybe right to consider this request. I'm currently creating my visual designer by doing the serialization on Android/iOS and communicating that back to the desktop app. It's ugly.

Sign In or Register to comment.