Uygulama Stilleri
FmgLib.MauiMarkup, XAML <Style> öğelerini güçlü tipli Style<T> sınıfıyla değiştirir. Bir stilin içinde kontrollerde kullandığınız aynı fluent özellik metotları setter'ları tanımlar — öğrenilecek tek API, kullanılacak iki bağlam.
Stil Tanımlama#
new Style<Button>(e => e
.TextColor(e => e.OnLight(Colors.White).OnDark(AppColors.Primary))
.BackgroundColor(e => e.OnLight(AppColors.Primary).OnDark(Colors.White))
.FontFamily("OpenSansRegular")
.FontSize(14)
.CornerRadius(8)
.Padding(new Thickness(14, 10))
.MinimumHeightRequest(44)
.MinimumWidthRequest(44))
Lambda bir SettersContext<Button> alır; her çağrı stile bir Setter ekler. Tema (OnLight/OnDark), platform, idiom ve DynamicResource builder'ları setter'ların içinde de aynen canlı kontrollerdeki gibi çalışır (Fluent Özellikler).
Style<T>, Microsoft.Maui.Controls.Style'a örtük dönüşür; MAUI'nin stil beklediği her yere konabilir.
Stilleri Uygulama#
Örtük — ResourceDictionary ile#
Kaynaklara eklenen stil, kapsamdaki hedef tipin tüm kontrollerine uygulanır:
// Uygulama geneli (App.cs)
this.Resources(
new ResourceDictionary
{
new Style<Button>(e => e.BackgroundColor(AppColors.Primary).CornerRadius(8)),
new Style<Frame>(e => e
.HasShadow(false)
.BorderColor(e => e.OnLight(AppColors.Gray200).OnDark(AppColors.Gray950))
.CornerRadius(8)),
new Style<Label>(e => e.TextColor(e => e.OnLight(Colors.Black).OnDark(Colors.White))),
}
);
Sayfa ve hatta layout düzeyinde Resources(...) kapsamı XAML'deki gibi çalışır.
Açık — kontrol başına#
var dangerButton = new Style<Button>(e => e
.BackgroundColor(Colors.Red)
.TextColor(Colors.White));
new Button().Text("Sil").Style(dangerButton)
Yaygın organizasyon deseni — statik stiller sınıfı:
public static class AppStyles
{
public static Style<Button> Primary { get; } = new(e => e
.BackgroundColor(AppColors.Primary)
.TextColor(Colors.White)
.CornerRadius(8));
public static Style<Button> Secondary { get; } = new(e => e
.BackgroundColor(Colors.Transparent)
.TextColor(AppColors.Primary));
public static ResourceDictionary Default { get; } = new()
{
Primary, Secondary,
new Style<Entry>(e => e.FontSize(16)),
};
}
// App içinde:
this.Resources(new ResourceDictionary().MergedDictionaries(AppStyles.Default));
// kontrol başına:
new Button().Text("Kaydet").Style(AppStyles.Primary)
Constructor Seçenekleri#
Style<T>, XAML stil özelliklerini yansıtan constructor'lara sahiptir:
// kalıtım
var baseText = new Style<Label>(e => e.FontFamily("OpenSansRegular").FontSize(14));
var heading = new Style<Label>(baseText, e => e.FontSize(24).FontAttributes(FontAttributes.Bold));
// türetilmiş tiplere uygula (örn. Button ve alt sınıfları)
var allButtons = new Style<Button>(applyToDerivedTypes: true, e => e.CornerRadius(8));
// ikisi birden
var special = new Style<Button>(basedOn: allButtons, applyToDerivedTypes: true, e => e.FontSize(16));
| Constructor parametresi | XAML karşılığı |
|---|---|
basedOn |
BasedOn="{StaticResource …}" |
applyToDerivedTypes |
ApplyToDerivedTypes="True" |
buildSetters lambda'sı |
<Setter> listesi |
Trigger, Visual State ve Aksiyon Ekleme#
Style<T> koleksiyon başlatıcı sözdizimini destekler; şunları ekleyebilirsiniz:
Setternesneleri (SomeProperty.Set(value)ile)TriggerBasenesneleri (Trigger'lar)VisualStateGroup/VisualState<T>nesneleri (Visual State'ler)Action<T>— stillenen her kontrole karşı çalıştırılan rastgele kod
new ResourceDictionary
{
new Style<Button>(e => e
.TextColor(e => e.OnLight(Colors.White).OnDark(AppColors.Primary))
.BackgroundColor(e => e.OnLight(AppColors.Primary).OnDark(Colors.White))
.FontSize(14)
.CornerRadius(8))
{
new VisualState<Button>(VisualStates.Button.Normal, e => e
.TextColor(e => e.OnLight(Colors.White).OnDark(AppColors.Primary))
.BackgroundColor(e => e.OnLight(AppColors.Primary).OnDark(Colors.White))),
new VisualState<Button>(VisualStates.Button.Disabled, e => e
.TextColor(e => e.OnLight(AppColors.Gray950).OnDark(AppColors.Gray200))
.BackgroundColor(e => e.OnLight(AppColors.Gray200).OnDark(AppColors.Gray600))),
},
};
Başlatıcı formunda ham setter ve trigger'ları karıştırma:
new Style<Entry>
{
Entry.BackgroundColorProperty.Set(Colors.Black),
Entry.TextColorProperty.Set(Colors.White),
new Trigger(typeof(Entry))
.Property(Entry.IsFocusedProperty)
.Value(true)
.Setters(new Setters<Entry>(e => e
.BackgroundColor(Colors.Yellow)
.TextColor(Colors.Black))),
}
Tema Stratejileri#
Üç tamamlayıcı araç; birlikte kullanın:
Setter'larda
OnLight/OnDark— temayı kendisi takip eder:C# new Style<Label>(e => e.TextColor(e => e.OnLight(Colors.Black).OnDark(Colors.White)))Bu ifade bir
AppThemeBindingüretir; dolayısıyla değer tema her değiştiğinde güncellenir — kullanıcı işletim sistemi temasını değiştirdiğinde de, uygulamaApplication.Current.UserAppThemeatadığında da. Ekranda hâlihazırda duran kontroller kendini yeniden boyar; sayfayı yeniden kurmanız ya da kaynak sözlüğünü boşaltıp doldurmanız gerekmez. (10.2.1 öncesinde değer kurulum anında bir kez çözülüyor ve sonraki değişiklikleri takip etmiyordu.)Dinamik kaynaklar — kullanıcı seçimli çalışma zamanı temaları:
C# new Style<Button>(e => e.BackgroundColor(e => e.DynamicResource("AccentColor"))) // tema değişimi: Application.Current!.Resources["AccentColor"] = Colors.Purple;Merged dictionary'ler — tüm stil setlerini değiştirme:
C# this.Resources(new ResourceDictionary().MergedDictionaries( isCompact ? CompactStyles.Default : ComfortableStyles.Default));
Stillerde Özel Genişletme Metotları#
Kendi fluent metotlarınız SettersContext<T> overload'larını uygularsa stillere katılır — dört overload'lı tam şablon Özel Genişletme Metotları sayfasında:
new Style<Label>(e => e
.FontSize(20) // yerleşik
.MyBrandTypography()) // sizin