Создаю индивидуальные Frame и View. Я объединил Frame и View в Page с Style ресурсами, как показано ниже.
<ContentPage.Resources>
<Style x:Key = "Style" TargetType = "local:MyFrame">
<Setter Property = "HorizontalOptions" Value = "FillAndExpand" />
<Setter Property = "BackgroundColor" Value = "LimeGreen" />
</Style>
</ContentPage.Resources>
<local:MyView>
<local:MyView.Views>
<local:MyFrame Style = "{StaticResource Style}"
HorizontalOptions = "FillAndExpand"
Title = "Number one" />
</local:MyView.Views>
</local:MyView>
public class MyView : ContentView
{
private readonly StackLayout _layout;
public ObservableCollection<View> Views { get; set; }
public MyView()
{
Views = new ObservableCollection<View>();
Views.CollectionChanged += OnViewsCollectionChanged;
_layout = new StackLayout();
Content = _layout;
}
private void OnViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
foreach (View view in e.OldItems)
_layout.Children.Remove(view);
if (e.NewItems != null)
foreach (View view in e.NewItems)
_layout.Children.Add(view);
}
}
public class MyFrame : Frame
{
private readonly Label _title;
public string Title { set => _title.Text = value; }
public MyFrame()
{
BackgroundColor = Color.LightPink;
_title = new Label
{
TextColor = Color.Black,
FontSize = 16,
};
Content = _title;
}
}
Я ожидал цвет LimeGreen на фоне MyFrame, потому что я установил MyFrame.Style в MainPage, однако фактический результат — светло-розовый.
Я предполагаю, что установка BackgroundColor в конструкторе MyFrame не означает установку по умолчанию. Тогда как я могу установить BackgroundColor по умолчанию для MyFrame?
Я упростил реальный проект до небольшого воспроизводимого проекта. Вот Github
Закомментируйте код BackgroundColor = Color.LightPink;, в результате получится цвет LimeGreen... Тогда как мне установить MyFrame.BackgroundColor по умолчанию?





Я мог бы воспроизвести вашу проблему, и я могу предложить следующую модификацию вашего кода, чтобы иметь возможность установить BackgroundColor по умолчанию для вашего представления MyFrame:
Чтобы решить вашу проблему, я изменил MyFrame, чтобы он был определен в Xaml:
MyFrameXaml.xaml
<?xml version = "1.0" encoding = "UTF-8"?>
<Frame xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
x:Class = "StyleDoesNotApply.MyFrameXAML"
BackgroundColor = "{Binding MyBackgroundColor}">
<Label x:Name = "title"
TextColor = "Black"
FontSize = "16"/>
</Frame>
Затем в коде задайте свойство MyBackgroundColor следующим образом:
MyFrameXaml.xaml.cs
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace StyleDoesNotApply
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyFrameXAML : Frame
{
public string Title { set => title.Text = value; }
public static readonly BindableProperty MyBackgroundColorProperty =
BindableProperty.Create(nameof(MyBackgroundColor), typeof(Color), typeof(MyFrame), Color.LightPink);
public Color MyBackgroundColor
{
get => (Color)GetValue(MyBackgroundColorProperty);
set => SetValue(MyBackgroundColorProperty, value);
}
public MyFrameXAML()
{
BindingContext = this;
InitializeComponent();
}
}
}
<ContentPage.Resources>
<Style x:Key = "Style" TargetType = "local:MyFrameXAML">
<Setter Property = "HorizontalOptions" Value = "StartAndExpand" />
<Setter Property = "MyBackgroundColor" Value = "LimeGreen" />
</Style>
</ContentPage.Resources>
<StackLayout>
<Label Text = "Style does apply!"
FontSize = "Title"
TextColor = "Black"/>
<local:MyView>
<local:MyView.Views>
<local:MyFrameXAML Style = "{StaticResource Style}"
HorizontalOptions = "FillAndExpand"
Title = "Number one" />
</local:MyView.Views>
</local:MyView>
</StackLayout>
Многоразовый код
public static BindableProperty Override(
this BindableProperty bindableProperty,
string propertyName = null,
Type returnType = null,
Type declaringType = null,
object defaultValue = null,
BindingMode defaultBindingMode = BindingMode.OneWay,
BindableProperty.ValidateValueDelegate validateValue = null,
BindableProperty.BindingPropertyChangedDelegate propertyChanged = null,
BindableProperty.BindingPropertyChangingDelegate propertyChanging = null,
BindableProperty.CoerceValueDelegate coerceValue = null,
BindableProperty.CreateDefaultValueDelegate defaultValueCreator = null)
{
if (string.IsNullOrEmpty(propertyName))
propertyName = bindableProperty.PropertyName;
if (returnType == null)
returnType = bindableProperty.ReturnType;
if (declaringType == null)
declaringType = bindableProperty.DeclaringType;
if (defaultValue == null)
defaultValue = bindableProperty.DefaultValue;
if (propertyChanged == null)
propertyChanged = (bindable, oldValue, newValue) =>
{
var property = bindableProperty.DeclaringType.GetProperty(bindableProperty.PropertyName);
property.SetValue(bindable, newValue);
};
return BindableProperty.Create(propertyName, returnType, declaringType, defaultValue, defaultBindingMode,
validateValue, propertyChanged, propertyChanging, coerceValue, defaultValueCreator);
}
public class MyFrame : Frame
{
// override existing BindableProperty
public static new readonly BindableProperty BackgroundColorProperty = VisualElement.BackgroundColorProperty.Override();
private readonly Label _title;
public string Title { set => _title.Text = value; }
public MyFrame()
{
BackgroundColor = Color.LightPink;
_title = new Label
{
TextColor = Color.Black,
FontSize = 16,
};
Content = _title;
}
}
Что вы имеете в виду по умолчанию?
StyleприменяетBackgroundColorпо умолчанию, а затем вы переопределяете его, явно настроив его под своим контролем.