Aracılığıyla paylaş


XAML İçindeki Yerel Görünümler

iOS, Android ve Evrensel Windows Platformu yerel görünümlere doğrudan XAML dosyalarından Xamarin.Forms başvurulabilir. Özellikler ve olay işleyicileri yerel görünümlerde ayarlanabilir ve görünümlerle Xamarin.Forms etkileşimde bulunabilir. Bu makalede XAML dosyalarından yerel görünümlerin Xamarin.Forms nasıl tükettiği gösterilmektedir.

XAML dosyasına yerel görünüm Xamarin.Forms eklemek için:

  1. Yerel görünümü içeren ad alanı için XAML dosyasına bir xmlns ad alanı bildirimi ekleyin.
  2. XAML dosyasında yerel görünümün bir örneğini oluşturun.

Önemli

Derlenmiş XAML, yerel görünümler kullanan tüm XAML sayfaları için devre dışı bırakılmalıdır. Bu, XAML sayfanızın arka planda kod sınıfını özniteliğiyle [XamlCompilation(XamlCompilationOptions.Skip)] süsleyerek gerçekleştirilebilir. XAML derlemesi hakkında daha fazla bilgi için, bkz . içinde XAML Derlemesi Xamarin.Forms.

Arka planda kod içeren bir dosyadan yerel görünüme başvurmak için Paylaşılan Varlık Projesi (SAP) kullanmanız ve platforma özgü kodu koşullu derleme yönergeleriyle sarmalamanız gerekir. Daha fazla bilgi için bkz . Koddan yerel görünümlere başvurma.

Yerel görünümleri kullanma

Aşağıdaki kod örneğinde, her platform için yerel görünümlerin bir Xamarin.FormsContentPage'e tüketilmesi gösterilmektedir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
        xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
        xmlns:androidLocal="clr-namespace:SimpleColorPicker.Droid;assembly=SimpleColorPicker.Droid;targetPlatform=Android"
        xmlns:win="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255,
            Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        x:Class="NativeViews.NativeViewDemo">
    <StackLayout Margin="20">
        <ios:UILabel Text="Hello World" TextColor="{x:Static ios:UIColor.Red}" View.HorizontalOptions="Start" />
        <androidWidget:TextView Text="Hello World" x:Arguments="{x:Static androidLocal:MainActivity.Instance}" />
        <win:TextBlock Text="Hello World" />
    </StackLayout>
</ContentPage>

Yerel görünüm ad alanı için ve assembly değerini belirtmenin clr-namespace yanı sıra, bir targetPlatform de belirtilmelidir. Bu, , , Android, (eşdeğeri UWP), macOS, GTK, Tizenveya WPFolarak ayarlanmalıdıriOS. WindowsUWP Çalışma zamanında, XAML ayrıştırıcısı, uygulamanın üzerinde çalıştığı platformla eşleşmeyen bir targetPlatform XML ad alanı ön eklerini yoksayar.

Her ad alanı bildirimi, belirtilen ad alanından herhangi bir sınıfa veya yapıya başvurmak için kullanılabilir. Örneğin, ios ad alanı bildirimi iOS UIKit ad alanından herhangi bir sınıfa veya yapıya başvurmak için kullanılabilir. Yerel görünümün özellikleri XAML aracılığıyla ayarlanabilir, ancak özellik ve nesne türlerinin eşleşmesi gerekir. Örneğin, UILabel.TextColor özelliği işaretleme uzantısını ve ios ad alanını kullanarak x:Static olarak ayarlanırUIColor.Red.

Bağlanabilir özellikler ve ekli bağlanabilir özellikler, söz dizimi kullanılarak Class.BindableProperty="value" yerel görünümlerde de ayarlanabilir. Her yerel görünüm, sınıfından türetilen platforma özgü NativeViewWrapper bir örnekte sarmalanır Xamarin.Forms.View . Yerel görünümde bağlanabilir bir özellik veya ekli bağlanabilir özellik ayarlamak, özellik değerini sarmalayıcıya aktarır. Örneğin, yerel görünümde ayarlanarak View.HorizontalOptions="Center" ortalanmış yatay düzen belirtilebilir.

Not

Stiller yalnızca nesneler tarafından BindableProperty yedeklenen özellikleri hedefleyebildiğinden, stillerin yerel görünümlerle kullanılamayabileceğini unutmayın.

Android pencere öğesi oluşturucuları genellikle bağımsız değişken olarak Android Context nesnesini gerektirir ve bu, sınıftaki MainActivity statik bir özellik aracılığıyla kullanılabilir hale getirilebilir. Bu nedenle, XAML'de bir Android pencere öğesi oluştururken, Context nesne genellikle işaretleme uzantısı ile x:Static özniteliği kullanılarak pencere öğesinin oluşturucusunda x:Arguments geçirilmelidir. Daha fazla bilgi için bkz . Bağımsız değişkenleri yerel görünümlere geçirme.

Not

Yerel görünümü ile x:Name adlandırmanın bir .NET Standart kitaplık projesinde veya Paylaşılan Varlık Projesi'nde (SAP) mümkün olmadığını unutmayın. Bunun yapılması, yerel türde bir değişken oluşturur ve bu da derleme hatasına neden olur. Ancak, yerel görünümler örneklerde ContentView sarmalanabilir ve SAP kullanılıyor olması koşuluyla arka planda kod dosyasında alınabilir. Daha fazla bilgi için bkz . Koddan yerel görünüme başvurma.

Yerel bağlamalar

Veri bağlama, bir kullanıcı arabirimini veri kaynağıyla eşitlemek için kullanılır ve uygulamanın Xamarin.Forms verileriyle nasıl görüntüleneceğini ve verilerle etkileşim kurmasını kolaylaştırır. Kaynak nesnenin arabirimi uygulaması koşuluylaINotifyPropertyChanged, kaynak nesnedeki değişiklikler bağlama çerçevesi tarafından otomatik olarak hedef nesneye gönderilir ve hedef nesnedeki değişiklikler isteğe bağlı olarak kaynak nesneye gönderilebilir.

Yerel görünümlerin özellikleri veri bağlamayı da kullanabilir. Aşağıdaki kod örneği, yerel görünümlerin özelliklerini kullanarak veri bağlamayı gösterir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
        xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
        xmlns:androidLocal="clr-namespace:SimpleColorPicker.Droid;assembly=SimpleColorPicker.Droid;targetPlatform=Android"
        xmlns:win="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255,
            Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        xmlns:local="clr-namespace:NativeSwitch"
        x:Class="NativeSwitch.NativeSwitchPage">
    <StackLayout Margin="20">
        <Label Text="Native Views Demo" FontAttributes="Bold" HorizontalOptions="Center" />
        <Entry Placeholder="This Entry is bound to the native switch" IsEnabled="{Binding IsSwitchOn}" />
        <ios:UISwitch On="{Binding Path=IsSwitchOn, Mode=TwoWay, UpdateSourceEventName=ValueChanged}"
            OnTintColor="{x:Static ios:UIColor.Red}"
            ThumbTintColor="{x:Static ios:UIColor.Blue}" />
        <androidWidget:Switch x:Arguments="{x:Static androidLocal:MainActivity.Instance}"
            Checked="{Binding Path=IsSwitchOn, Mode=TwoWay, UpdateSourceEventName=CheckedChange}"
            Text="Enable Entry?" />
        <win:ToggleSwitch Header="Enable Entry?"
            OffContent="No"
            OnContent="Yes"
            IsOn="{Binding IsSwitchOn, Mode=TwoWay, UpdateSourceEventName=Toggled}" />
    </StackLayout>
</ContentPage>

sayfasında özelliği özelliğine NativeSwitchPageViewModel.IsSwitchOn bağlanan bir EntryIsEnabled içerir. BindingContext Sayfanın öğesi arka planda kod dosyasında sınıfının yeni bir örneğine NativeSwitchPageViewModel ayarlanır ve ViewModel sınıfı arabirimini INotifyPropertyChanged uygular.

Sayfa ayrıca her platform için yerel bir anahtar içerir. Her yerel anahtar, özelliğin NativeSwitchPageViewModel.IsSwitchOn değerini güncelleştirmek için bir TwoWay bağlama kullanır. Bu nedenle, anahtar kapalıyken devre Entry dışı bırakılır ve anahtar açık Entry olduğunda etkin olur. Aşağıdaki ekran görüntüleri her platformda bu işlevi gösterir:

Yerel Anahtar Devre DışıYerel Anahtar Etkin

İki yönlü bağlamalar, yerel özelliğin INotifyPropertyChangeduygulaması veya iOS üzerinde Anahtar-Değer Gözlemlemeyi (KVO) desteklemesi veya UWP üzerinde olması DependencyProperty koşuluyla otomatik olarak desteklenir. Ancak, birçok yerel görünüm özellik değişikliği bildirimini desteklemez. Bu görünümler için, bağlama ifadesinin bir parçası olarak bir UpdateSourceEventName özellik değeri belirtebilirsiniz. Bu özellik, yerel görünümde hedef özellik değiştiğinde sinyal veren bir olayın adına ayarlanmalıdır. Ardından, yerel anahtarın değeri değiştiğinde Binding , kullanıcıya anahtar değerini değiştirdiği bildirilir ve NativeSwitchPageViewModel.IsSwitchOn özellik değeri güncelleştirilir.

Bağımsız değişkenleri yerel görünümlere geçirme

Oluşturucu bağımsız değişkenleri, işaretleme uzantısıyla x:Argumentsx:Static özniteliği kullanılarak yerel görünümlere geçirilebilir. Buna ek olarak, yerel görünüm fabrika yöntemleri (public static yöntemleri tanımlayan sınıf veya yapı ile aynı türde nesneleri veya değerleri döndüren yöntemler) özniteliği kullanılarak yöntemin adı ve özniteliği kullanılarak x:FactoryMethodx:Arguments bağımsız değişkenleri belirtilerek çağrılabilir.

Aşağıdaki kod örneği her iki tekniği de gösterir:

<ContentPage ...
        xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
        xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
        xmlns:androidGraphics="clr-namespace:Android.Graphics;assembly=Mono.Android;targetPlatform=Android"
        xmlns:androidLocal="clr-namespace:SimpleColorPicker.Droid;assembly=SimpleColorPicker.Droid;targetPlatform=Android"
        xmlns:winControls="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        xmlns:winMedia="clr-namespace:Windows.UI.Xaml.Media;assembly=Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        xmlns:winText="clr-namespace:Windows.UI.Text;assembly=Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        xmlns:winui="clr-namespace:Windows.UI;assembly=Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows">
        ...
        <ios:UILabel Text="Simple Native Color Picker" View.HorizontalOptions="Center">
            <ios:UILabel.Font>
                <ios:UIFont x:FactoryMethod="FromName">
                    <x:Arguments>
                        <x:String>Papyrus</x:String>
                        <x:Single>24</x:Single>
                    </x:Arguments>
                </ios:UIFont>
            </ios:UILabel.Font>
        </ios:UILabel>
        <androidWidget:TextView x:Arguments="{x:Static androidLocal:MainActivity.Instance}"
                    Text="Simple Native Color Picker"
                    TextSize="24"
                    View.HorizontalOptions="Center">
            <androidWidget:TextView.Typeface>
                <androidGraphics:Typeface x:FactoryMethod="Create">
                    <x:Arguments>
                        <x:String>cursive</x:String>
                        <androidGraphics:TypefaceStyle>Normal</androidGraphics:TypefaceStyle>
                    </x:Arguments>
                </androidGraphics:Typeface>
            </androidWidget:TextView.Typeface>
        </androidWidget:TextView>
        <winControls:TextBlock Text="Simple Native Color Picker"
                    FontSize="20"
                    FontStyle="{x:Static winText:FontStyle.Italic}"
                    View.HorizontalOptions="Center">
            <winControls:TextBlock.FontFamily>
                <winMedia:FontFamily>
                    <x:Arguments>
                        <x:String>Georgia</x:String>
                    </x:Arguments>
                </winMedia:FontFamily>
            </winControls:TextBlock.FontFamily>
        </winControls:TextBlock>
        ...
</ContentPage>

UIFont.FromName fabrika yöntemi özelliği iOS'ta yeni UIFont olarak ayarlamak UILabel.Font için kullanılır. UIFont Ad ve boyut, özniteliğin alt x:Arguments öğeleri olan yöntem bağımsız değişkenleri tarafından belirtilir.

Typeface.Create Fabrika yöntemi, özelliği Android'de TextView.Typeface yeni Typeface olarak ayarlamak için kullanılır. Aile Typeface adı ve stili, özniteliğin alt x:Arguments öğeleri olan yöntem bağımsız değişkenleri tarafından belirtilir.

OluşturucuFontFamily, özelliği Evrensel Windows Platformu (UWP) üzerinde yeni FontFamily bir olarak ayarlamak TextBlock.FontFamily için kullanılır. Ad FontFamily , özniteliğinin alt x:Arguments öğesi olan yöntem bağımsız değişkeni tarafından belirtilir.

Not

Bağımsız değişkenlerin oluşturucu veya fabrika yöntemi için gereken türlerle eşleşmesi gerekir.

Aşağıdaki ekran görüntüleri, yazı tipini farklı yerel görünümlerde ayarlamak için fabrika yöntemini ve oluşturucu bağımsız değişkenlerini belirtmenin sonucunu gösterir:

Yerel Görünümlerde Yazı Tiplerini Ayarlama

XAML'de bağımsız değişkenleri geçirme hakkında daha fazla bilgi için bkz . XAML'de Bağımsız Değişkenleri Geçirme.

Koddan yerel görünümlere bakın

Bir yerel görünümü özniteliğiyle adlandırmak mümkün olmasa da, yerel görünümün bir öznitelik değeri belirten x:Name bir alt öğesi olması koşuluylax:Name, XAML dosyasında bildirilen bir yerel görünüm örneğini Paylaşılan Erişim Projesindeki arka planda kod dosyasından ContentView almak mümkündür. Ardından, arka planda kod dosyasındaki koşullu derleme yönergelerinin içinde şunları yapmalısınız:

  1. ContentView.Content Özellik değerini alın ve platforma özgü NativeViewWrapper bir türe yayınlayın.
  2. NativeViewWrapper.NativeElement özelliğini alın ve yerel görünüm türüne yayınlayın.

Yerel API daha sonra istenen işlemleri gerçekleştirmek için yerel görünümde çağrılabilir. Bu yaklaşım, farklı platformlar için birden çok XAML yerel görünümünün aynı ContentViewalt öğe olabileceği avantajını da sunar. Aşağıdaki kod örneği bu tekniği gösterir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
        xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
        xmlns:androidLocal="clr-namespace:SimpleColorPicker.Droid;assembly=SimpleColorPicker.Droid;targetPlatform=Android"
        xmlns:winControls="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255,
            Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        xmlns:local="clr-namespace:NativeViewInsideContentView"
        x:Class="NativeViewInsideContentView.NativeViewInsideContentViewPage">
    <StackLayout Margin="20">
        <ContentView x:Name="contentViewTextParent" HorizontalOptions="Center" VerticalOptions="CenterAndExpand">
            <ios:UILabel Text="Text in a UILabel" TextColor="{x:Static ios:UIColor.Red}" />
            <androidWidget:TextView x:Arguments="{x:Static androidLocal:MainActivity.Instance}"
                Text="Text in a TextView" />
              <winControls:TextBlock Text="Text in a TextBlock" />
        </ContentView>
        <ContentView x:Name="contentViewButtonParent" HorizontalOptions="Center" VerticalOptions="EndAndExpand">
            <ios:UIButton TouchUpInside="OnButtonTap" View.HorizontalOptions="Center" View.VerticalOptions="Center" />
            <androidWidget:Button x:Arguments="{x:Static androidLocal:MainActivity.Instance}"
                Text="Scale and Rotate Text"
                Click="OnButtonTap" />
            <winControls:Button Content="Scale and Rotate Text" />
        </ContentView>
    </StackLayout>
</ContentPage>

Yukarıdaki örnekte, her platform için yerel görünümler denetimlerin ContentView alt öğeleridir ve x:Name arka planda öğesini almak ContentView için öznitelik değeri kullanılır:

public partial class NativeViewInsideContentViewPage : ContentPage
{
    public NativeViewInsideContentViewPage()
    {
        InitializeComponent();

#if __IOS__
        var wrapper = (Xamarin.Forms.Platform.iOS.NativeViewWrapper)contentViewButtonParent.Content;
        var button = (UIKit.UIButton)wrapper.NativeView;
        button.SetTitle("Scale and Rotate Text", UIKit.UIControlState.Normal);
        button.SetTitleColor(UIKit.UIColor.Black, UIKit.UIControlState.Normal);
#endif
#if __ANDROID__
        var wrapper = (Xamarin.Forms.Platform.Android.NativeViewWrapper)contentViewTextParent.Content;
        var textView = (Android.Widget.TextView)wrapper.NativeView;
        textView.SetTextColor(Android.Graphics.Color.Red);
#endif
#if WINDOWS_UWP
        var textWrapper = (Xamarin.Forms.Platform.UWP.NativeViewWrapper)contentViewTextParent.Content;
        var textBlock = (Windows.UI.Xaml.Controls.TextBlock)textWrapper.NativeElement;
        textBlock.Foreground = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.Red);
        var buttonWrapper = (Xamarin.Forms.Platform.UWP.NativeViewWrapper)contentViewButtonParent.Content;
        var button = (Windows.UI.Xaml.Controls.Button)buttonWrapper.NativeElement;
        button.Click += (sender, args) => OnButtonTap(sender, EventArgs.Empty);
#endif
    }

    async void OnButtonTap(object sender, EventArgs e)
    {
        contentViewButtonParent.Content.IsEnabled = false;
        contentViewTextParent.Content.ScaleTo(2, 2000);
        await contentViewTextParent.Content.RotateTo(360, 2000);
        contentViewTextParent.Content.ScaleTo(1, 2000);
        await contentViewTextParent.Content.RelRotateTo(360, 2000);
        contentViewButtonParent.Content.IsEnabled = true;
    }
}

Özelliğine ContentView.Content , sarmalanmış yerel görünümü platforma özgü NativeViewWrapper bir örnek olarak almak için erişilir. Daha NativeViewWrapper.NativeElement sonra yerel görünümü yerel türü olarak almak için özelliğine erişilir. Daha sonra istenen işlemleri gerçekleştirmek için yerel görünümün API'si çağrılır.

Her yerel düğme bir dokunma olayına yanıt olarak bir EventHandler temsilci tükettiğinden, iOS ve Android yerel düğmeleri aynı OnButtonTap olay işleyicisini paylaşır. Ancak, Evrensel Windows Platformu (UWP) bu örnekte olay işleyicisini OnButtonTap kullanan ayrı RoutedEventHandlerbir kullanır. Bu nedenle, yerel bir düğmeye tıklandığında olay OnButtonTap işleyicisi yürütülür ve bu da adlandırılmış contentViewTextParentiçinde ContentView yer alan yerel denetimi ölçeklendirir ve döndürür. Aşağıdaki ekran görüntüleri, her platformda gerçekleşen bu durumu gösterir:

Yerel Denetim İçeren ContentView

Alt sınıf yerel görünümleri

Birçok iOS ve Android yerel görünümü, denetimi ayarlamak için özellikler yerine yöntemler kullandığından XAML'de örnek oluşturma için uygun değildir. Bu sorunun çözümü, denetimi ayarlamak için özellikleri kullanan ve platformdan bağımsız olaylar kullanan daha XAML dostu bir API tanımlayan sarmalayıcılardaki yerel görünümleri alt sınıfa almaktır. Sarmalanan yerel görünümler daha sonra Paylaşılan Varlık Projesi'ne (SAP) yerleştirilebilir ve koşullu derleme yönergeleriyle çevrelenebilir veya platforma özgü projelere yerleştirilebilir ve bir .NET Standart kitaplık projesinde XAML'den başvurulabilir.

Aşağıdaki kod örneği, alt sınıflanmış yerel görünümleri kullanan bir Xamarin.Forms sayfayı gösterir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
        xmlns:iosLocal="clr-namespace:SubclassedNativeControls.iOS;assembly=SubclassedNativeControls.iOS;targetPlatform=iOS"
        xmlns:android="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
        xmlns:androidLocal="clr-namespace:SimpleColorPicker.Droid;assembly=SimpleColorPicker.Droid;targetPlatform=Android"
        xmlns:androidLocal="clr-namespace:SubclassedNativeControls.Droid;assembly=SubclassedNativeControls.Droid;targetPlatform=Android"
        xmlns:winControls="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255,
            Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        xmlns:local="clr-namespace:SubclassedNativeControls"
        x:Class="SubclassedNativeControls.SubclassedNativeControlsPage">
    <StackLayout Margin="20">
        <Label Text="Subclassed Native Views Demo" FontAttributes="Bold" HorizontalOptions="Center" />
        <StackLayout Orientation="Horizontal">
          <Label Text="You have chosen:" />
          <Label Text="{Binding SelectedFruit}" />      
        </StackLayout>
        <iosLocal:MyUIPickerView ItemsSource="{Binding Fruits}"
            SelectedItem="{Binding SelectedFruit, Mode=TwoWay, UpdateSourceEventName=SelectedItemChanged}" />
        <androidLocal:MySpinner x:Arguments="{x:Static androidLocal:MainActivity.Instance}"
            ItemsSource="{Binding Fruits}"
            SelectedObject="{Binding SelectedFruit, Mode=TwoWay, UpdateSourceEventName=ItemSelected}" />
        <winControls:ComboBox ItemsSource="{Binding Fruits}"
            SelectedItem="{Binding SelectedFruit, Mode=TwoWay, UpdateSourceEventName=SelectionChanged}" />
    </StackLayout>
</ContentPage>

Sayfa, yerel denetimden Label kullanıcı tarafından seçilen meyveyi görüntüleyen bir içerir. özelliğine LabelSubclassedNativeControlsPageViewModel.SelectedFruit bağlanır. BindingContext Sayfanın öğesi arka planda kod dosyasında sınıfının yeni bir örneğine SubclassedNativeControlsPageViewModel ayarlanır ve ViewModel sınıfı arabirimini INotifyPropertyChanged uygular.

Sayfa ayrıca her platform için yerel bir seçici görünümü içerir. Her yerel görünüm, özelliğini SubclassedNativeControlsPageViewModel.Fruits koleksiyona bağlayarak ItemSource meyve koleksiyonunu görüntüler. Bu, kullanıcının aşağıdaki ekran görüntülerinde gösterildiği gibi bir meyve seçmesine olanak tanır:

Alt Sınıflanmış Yerel Görünümler

iOS ve Android'de yerel seçiciler denetimleri ayarlamak için yöntemleri kullanır. Bu nedenle, bu seçicilerin XAML kullanımına uygun hale getirmek için özellikleri kullanıma sunmaları için alt sınıfa alınması gerekir. Evrensel Windows Platformu (UWP) ComboBox üzerinde , zaten XAML dostudur ve bu nedenle alt sınıflama gerektirmez.

iOS

iOS uygulaması görünümü alt sınıflarına alır UIPickerView ve özellikleri ve XAML'den kolayca kullanılabilecek bir olayı kullanıma sunar:

public class MyUIPickerView : UIPickerView
{
    public event EventHandler<EventArgs> SelectedItemChanged;

    public MyUIPickerView()
    {
        var model = new PickerModel();
        model.ItemChanged += (sender, e) =>
        {
            if (SelectedItemChanged != null)
            {
                SelectedItemChanged.Invoke(this, e);
            }
        };
        Model = model;
    }

    public IList<string> ItemsSource
    {
        get
        {
            var pickerModel = Model as PickerModel;
            return (pickerModel != null) ? pickerModel.Items : null;
        }
        set
        {
            var model = Model as PickerModel;
            if (model != null)
            {
                model.Items = value;
            }
        }
    }

    public string SelectedItem
    {
        get { return (Model as PickerModel).SelectedItem; }
        set { }
    }
}

MyUIPickerView sınıfı, ve özelliklerini ve SelectedItem bir SelectedItemChanged olayı kullanıma sunarItemsSource. , UIPickerView özellikler ve olay tarafından MyUIPickerView erişilen bir temel UIPickerViewModel veri modeli gerektirir. Veri UIPickerViewModel modeli sınıfı tarafından PickerModel sağlanır:

class PickerModel : UIPickerViewModel
{
    int selectedIndex = 0;
    public event EventHandler<EventArgs> ItemChanged;
    public IList<string> Items { get; set; }

    public string SelectedItem
    {
        get
        {
            return Items != null && selectedIndex >= 0 && selectedIndex < Items.Count ? Items[selectedIndex] : null;
        }
    }

    public override nint GetRowsInComponent(UIPickerView pickerView, nint component)
    {
        return Items != null ? Items.Count : 0;
    }

    public override string GetTitle(UIPickerView pickerView, nint row, nint component)
    {
        return Items != null && Items.Count > row ? Items[(int)row] : null;
    }

    public override nint GetComponentCount(UIPickerView pickerView)
    {
        return 1;
    }

    public override void Selected(UIPickerView pickerView, nint row, nint component)
    {
        selectedIndex = (int)row;
        if (ItemChanged != null)
        {
            ItemChanged.Invoke(this, new EventArgs());
        }
    }
}

PickerModel sınıfı, özelliği aracılığıyla sınıfı için MyUIPickerView temel alınan depolamayı Items sağlar. Seçilen öğe değişikliklerinde MyUIPickerView yöntemi Selected yürütülür ve bu yöntem seçili dizini güncelleştirir ve olayı başlatır ItemChanged . Bu, özelliğin SelectedItem her zaman kullanıcı tarafından seçilen son öğeyi döndürmesini sağlar. Buna ek olarak, PickerModel sınıfı örneği ayarlamak MyUIPickerView için kullanılan yöntemleri geçersiz kılar.

Android

Android uygulaması görünümün alt sınıflarını oluşturur Spinner ve özellikleri ve XAML'den kolayca kullanılabilecek bir olayı kullanıma sunar:

class MySpinner : Spinner
{
    ArrayAdapter adapter;
    IList<string> items;

    public IList<string> ItemsSource
    {
        get { return items; }
        set
        {
            if (items != value)
            {
                items = value;
                adapter.Clear();

                foreach (string str in items)
                {
                    adapter.Add(str);
                }
            }
        }
    }

    public string SelectedObject
    {
        get { return (string)GetItemAtPosition(SelectedItemPosition); }
        set
        {
            if (items != null)
            {
                int index = items.IndexOf(value);
                if (index != -1)
                {
                    SetSelection(index);
                }
            }
        }
    }

    public MySpinner(Context context) : base(context)
    {
        ItemSelected += OnBindableSpinnerItemSelected;

        adapter = new ArrayAdapter(context, Android.Resource.Layout.SimpleSpinnerItem);
        adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
        Adapter = adapter;
    }

    void OnBindableSpinnerItemSelected(object sender, ItemSelectedEventArgs args)
    {
        SelectedObject = (string)GetItemAtPosition(args.Position);
    }
}

MySpinner sınıfı, ve özelliklerini ve SelectedObject bir ItemSelected olayı kullanıma sunarItemsSource. sınıfı tarafından MySpinner görüntülenen öğeler görünümle ilişkilendirilmiş tarafından Adapter sağlanır ve öğeler özelliği ilk ayarlandığında içine AdapterItemsSource doldurulur. Sınıftaki seçili öğe her değiştiğinde MySpinner , OnBindableSpinnerItemSelected olay işleyicisi özelliğini güncelleştirir SelectedObject .