Есть ли способ отделить стиль от моего XAML в Xamarin.Forms

Я использую Xamarin.Forms в PCL со страницами XAML. Единственный способ, которым я определил стиль моего элемента управления, - использовать встроенный синтаксис.

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

Я бы предпочел использовать такую ​​структуру, как эта:

<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)

Однако элемент Style еще не поддерживается (пока). Кто-нибудь преуспел в отделении макета из содержимого?

FYI: Я также разместил этот вопрос на форумах Xamarin, поэтому любой, кто попал сюда через google, может захотеть также проверить эту страницу: http://forums.xamarin.com/discussion/19287/styling-of-xamarin-xaml#latest

Ответ 1

Из Xamarin.Forms 1.3 вы получаете больше вариантов стиля.

Xamarin.Forms 1.3 Предварительный просмотр технологий

  • Поддержка стилей в XAML и в коде
  • Разрешить стили основываться на DynamicResources через Style.BaseResourceKey
  • Добавить стили, специфичные для платформы, через Device.Styles(поддерживает динамический тип iOS)

Ответ 2

Стиль не такой уж сложный [править]. Вы можете реализовать свои собственные, как я только что сделал для этого ответа.

Вот что будет выглядеть Xaml:

<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>

поддерживающий код будет выглядеть так:

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);
        }
    }
}

Очевидно, что код, выполняющий назначение, очень легкий, и вам, возможно, придется адаптировать его к вашим потребностям (поддержка перечислений и т.д.), но он работает в этом упрощенном случае.

Я уверен, что это поможет.

Ответ 3

Теперь доступна поддержка стиля:

<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>

Ответ 4

Я рассматриваю этот вопрос с самим Xamarin Forms, будучи разработчиком Silverlight.

Дополнительным подходом было бы создание собственных элементов управления ( "Представления" в терминах Xamarin), либо в XAML, либо в коде, и использовать их при построении интерфейса.

Ответ 5

Мне удалось создать код, который ближе к ResourceDictionary, к которому я более привык в WPF/Silverlight, и удалить его с фактической страницы (просмотра)

  • Вместо того, чтобы иметь только App.cs, я создал новый файл xaml.. App.xaml вместе с ним, сопровождающий код-код App.xaml.cs. Я взял то, что было в App.cs, и поместил его в App.xaml.cs.

    public partial class App : Application
    {
        public App()
        {
           var _mainView = new MainView();
           var _navPage = new NavigationPage(_mainView);
           MainPage = _navPage;
        }
    
       //.. the methods below are currently empty on mine, 
       //still figuring out some of the front end ..
       protected override void OnStart(){ }
       protected override void OnSleep(){ }
       protected override void OnResume(){ }    
    

    }

  • Это позволило мне в App.xaml объявить ресурсы приложения, которые я могу использовать для других представлений:

      

        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Setter Property="TextColor" Value="Blue"/>
            <!-- note: I tried Foreground and got errors, but once I 
                 used TextColor as the property, it ran fine and the 
                 text of the button I had changed color to what I expected -->
            <Setter Property="BackgroundColor" Value="White"/>
            <!-- note: I tried Background and got errors, but once I 
                 used BackgroundColor as the property, it ran fine and the 
                 background of the button I had changed color -->
        </Style>
    
    </ResourceDictionary>
    

И затем я смог использовать стиль на своих страницах, используя StaticResource

<Button Text="Inquiry" Style="{StaticResource buttonStyle}"/>

Есть, вероятно, десятки способов, может быть, даже лучше - но это помогло мне сохранить все мои стили в одном месте (App.xaml)

P.S. Я не знаю, почему это не форматирование примера кода, я пробовал несколько раз, но, надеюсь, вы все еще это понимаете.