Есть ли способ отделить стиль от моего 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. Я не знаю, почему это не форматирование примера кода, я пробовал несколько раз, но, надеюсь, вы все еще это понимаете.