Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to separate the styling from my XAML in Xamarin.Forms

I'm using Xamarin.Forms in a PCL with the XAML pages. The only way I figured out to style my controls is to use an inline syntax.

<Button Text="Inquiry" TextColor="Blue" />

I would prefer to use a structure like this one:

<Page.Resources>
    <Style TargetType="Button">
        <Setter Property="BorderThickness" Value="5" />
        <Setter Property="Foreground" Value="Blue" />
    </Style>
</Page.Resources>

(http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh465381.aspx)

However, the Style element is not (yet) supported. Has anyone succeeded in separating the layout from the contents?

FYI: I've also posted this question in Xamarin forums, so anyone who got here by google might want to also check out this page: http://forums.xamarin.com/discussion/19287/styling-of-xamarin-xaml#latest

like image 530
Yoeri Avatar asked Jun 26 '14 08:06

Yoeri


People also ask

What replaced XAML?

The XAML Previewer has been deprecated in Visual Studio 2019 version 16.8 and Visual Studio for Mac version 8.8, and replaced by the XAML Hot Reload feature in Visual Studio 2019 version 16.9 and Visual Studio for Mac version 8.9.

Do you have to use XAML in Xamarin forms?

XAML is never required in a Xamarin. Forms program, but it is often more succinct and more visually coherent than equivalent code, and potentially toolable.

Can you use CSS in XAML?

Currently, all of the styling that's possible with XAML styling cannot be performed with CSS. However, XAML styles can be used to supplement CSS for properties that are currently unsupported by Xamarin.

What is dynamic resource in Xamarin forms?

The DynamicResource markup extension is similar to the StaticResource markup extension in that both use a dictionary key to fetch a value from a ResourceDictionary . However, while the StaticResource performs a single dictionary lookup, the DynamicResource maintains a link to the dictionary key.


3 Answers

Style is not that hard [citation needed]. You can implement your own, as I just did for the purpose of this answer.

Here's what the Xaml will look like:

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:YourNS;assembly=YourAssembly">
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:Style x:Key="buttonStyle">
                <local:Setter Property="BorderWidth" Value="5"/>
            </local:Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <Button Text="Foo" local:Style.Style="{StaticResource buttonStyle}" x:Name="button"/>
</ContentPage>

the supporting code will look like:

namespace YourNS
{

    public class Setter {
        public string Property { get; set; }
        public string Value { get; set; }
    }

    [ContentProperty ("Children")]
    public class Style
    {
        public Style ()
        {
            Children = new List<Setter> ();
        }

        public IList<Setter> Children { get; private set; }

        public static readonly BindableProperty StyleProperty = 
            BindableProperty.CreateAttached<Style, Style> (bindable => GetStyle (bindable), default(Style), 
                propertyChanged: (bindable, oldvalue, newvalue)=>{
                    foreach (var setter in newvalue.Children) {
                        var pinfo = bindable.GetType().GetRuntimeProperty (setter.Property);
                        pinfo.SetMethod.Invoke (bindable,new [] {Convert.ChangeType (setter.Value, pinfo.PropertyType.GetTypeInfo())});
                    }

                });

        public static Style GetStyle (BindableObject bindable)
        {
            return (Style)bindable.GetValue (StyleProperty);
        }

        public static void SetStyle (BindableObject bindable, Style value)
        {
            bindable.SetValue (StyleProperty, value);
        }
    }
}

Obviously, the code doing the assignation is very light and you might have to adapt it to your needs (support enums, etc.), but it works in this simplistic case.

I'm sure it'll help.

like image 110
Stephane Delcroix Avatar answered Oct 16 '22 19:10

Stephane Delcroix


Style support is now available:

<ContentPage.Resources>
   <ResourceDictionary>

  <Style TargetType="Label">
    <Setter Property="HorizontalOptions" Value="LayoutOptions.Center" />
    <Setter Property="VerticalOptions" Value="LayoutOptions.Center" />
    <Setter Property="FontSize" Value="48" />
    <Setter Property="FontAttributes" Value="Bold, Italic" />
    <Setter Property="Opacity" Value=".5" />
    <Setter Property="TextColor" Value="Black" />
    <Setter Property="Text" Value="Copied" />
    <Setter Property="IsVisible" Value="False" />
  </Style>

  </ResourceDictionary>
</ContentPage.Resources>
like image 34
Scott Nimrod Avatar answered Oct 16 '22 18:10

Scott Nimrod


From Xamarin.Forms 1.3 you get more styling options.

Xamarin.Forms 1.3 Technology Preview

  • Support styles in XAML and in code
  • Allow styles to be based on DynamicResources via Style.BaseResourceKey
  • Add platform specific styles via Device.Styles (supports iOS dynamic type)
like image 1
RoelV Avatar answered Oct 16 '22 18:10

RoelV