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

Örnek indir Örneği indirin

iOS, Android ve Evrensel Windows Platformu yerel görünümler XAML dosyalarından doğrudan başvuruda bulunabilir Xamarin.Forms . özellikler ve olay işleyicileri yerel görünümlerde ayarlanabilir ve iOS, Android 'in yerel görünümleriyle etkileşime girebilirler ve Evrensel Windows Platformu doğrudan Xamarin.FormsXamarin.Forms görünümlerden bulunabilir. Bu makalede, XAML dosyalarından yerel görünümlerin nasıl kullanılacağı gösterilmektedir Xamarin.Forms .

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

  1. xmlnsYerel görünümü içeren ad alanı IÇIN xaml dosyasında bir 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 XAML sayfaları için devre dışı bırakılmalıdır. Bu, XAML sayfanız için arka plan kod sınıfı, özniteliğiyle birlikte dekorasyon ile gerçekleştirilebilir [XamlCompilation(XamlCompilationOptions.Skip)] . XAML derlemesi hakkında daha fazla bilgi için bkz XAML Compilation in Xamarin.Forms ..

arka plan kod dosyasından yerel bir görünüme başvurmak için, paylaşılan bir varlık Project (SAP) kullanmanız ve platforma özgü kodu koşullu derleme yönergeleriyle sarmalısınız. Daha fazla bilgi için bkz. Koddan yerel görünümlere bakın.

Yerel görünümleri kullanma

Aşağıdaki kod örneği, için her bir platform için yerel görünümler kullanmayı göstermektedir Xamarin.FormsContentPage :

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

clr-namespaceVe assembly yerel bir görünüm ad alanı için ve belirtmek için targetPlatform de belirtilmesi gerekir. Bu,,,,,,,, veya olarak ayarlanmalıdır iOSAndroidUWPWindowsUWPmacOSGTKTizenWPF . Çalışma zamanında, XAML ayrıştırıcısı targetPlatform uygulamanın üzerinde çalıştığı platformla eşleşmeyen BIR XML ad alanı öneklerini yok sayacaktır.

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 ad alanından herhangi bir sınıfa veya yapıya başvurmak için kullanılabilir UIKit . 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 UIColor.Redx:Static biçimlendirme uzantısını ve ad alanını kullanmak üzere ayarlanır ios .

Bağlanabilir Özellikler ve bağlı bağlanabilir özellikler, sözdizimi kullanılarak yerel görünümlerde de ayarlanabilir Class.BindableProperty="value" . Her yerel görünüm, sınıfından türetilen platforma özgü bir örneğe sarmalanır NativeViewWrapperXamarin.Forms.View . Yerel görünümde bağlanabilir bir özelliğin veya bağlı bağlanabilir özelliğin ayarlanması, özellik değerini sarmalayıcıya aktarır. Örneğin, ortalanmış yatay düzen yerel görünüm ayarı ile belirtilebilir View.HorizontalOptions="Center" .

Not

Stiller yalnızca nesneler tarafından desteklenen özellikleri hedeflebildiğinden, bu stillerin yerel görünümlerle birlikte kullanılamayacağını unutmayın BindableProperty .

Android pencere öğesi oluşturucuları, genellikle Context bir bağımsız değişken olarak Android nesnesi gerektirir ve bu, sınıfındaki statik bir özellik aracılığıyla kullanılabilir hale getirilebilir MainActivity . Bu nedenle, XAML 'de bir Android pencere öğesi oluştururken, Contextx:Arguments bir biçimlendirme uzantısı olan özniteliği kullanılarak nesnenin genellikle pencere öğesinin oluşturucusuna geçirilmesi gerekir x:Static . Daha fazla bilgi için bkz. bağımsız değişkenleri yerel görünümlere geçirme.

Not

ile yerel bir görünümü adlandırmanın x:Name .NET Standard kitaplık projesinde veya paylaşılan varlık Project (SAP) içinde mümkün olmadığına 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 ContentView örneklerde kaydırılmış ve bır SAP kullanıldığı için arka plan kod dosyasında alınmış olabilir. Daha fazla bilgi için bkz. Koddan yerel görünüme bakın.

Yerel bağlamalar

Veri bağlama, bir kullanıcı arabirimini veri kaynağıyla eşleştirmek için kullanılır ve bir Xamarin.Forms uygulamanın verilerini nasıl görüntüleyip etkileşime gireceğini basitleştirir. Kaynak nesne INotifyPropertyChanged arabirimini gerçekleştirdiğinden, INotifyPropertyChanged 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 nesnesine itilmiş olabilir.

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>

Sayfa, Entry Xamarin_Forms Entry "Data-LinkType =" Absolute-path ">IsEnabled özelliği özelliğe bağlamakta olan bir _VisualElement_IsEnabled içeriyor NativeSwitchPageViewModel.IsSwitchOn . Xamarin_Forms _BindableObject_BindingContext "Data-LinkType =" Absolute-path ">, BindingContextNativeSwitchPageViewModel arabirimi uygulayan ViewModel sınıfıyla birlikte arka plan kod dosyasında sınıfının yeni bir örneğine ayarlanır INotifyPropertyChanged .

Bu sayfada her platform için bir yerel anahtar de bulunur. Her yerel anahtar, TwoWay özelliğin değerini güncelleştirmek için bir Xamarin_Forms _BindingMode_TwoWay "Data-LinkType =" absolute-path ">bağlamayı kullanır NativeSwitchPageViewModel.IsSwitchOn . Bu nedenle, anahtar kapalıyken, Entry devre dışıdır ve anahtar açık olduğunda Entry etkinleştirilir. Aşağıdaki ekran görüntüleri her platformda bu işlevselliği gösterir:

Yerel anahtar devre dışıyerel anahtar etkin

Yerel özelliğin, INotifyPropertyChanged iOS üzerinde Key-Value gözeyi (KVO) uyguladığı veya desteklediği ya da UWP üzerinde olduğu için, iki yönlü bağlamalar otomatik olarak desteklenir DependencyProperty . Ancak, birçok yerel görünüm özellik değişiklik bildirimini desteklemez. Bu görünümlerde, bağlama ifadesinin bir parçası olarak bir Xamarin_Forms _Binding_UpdateSourceEventName "Data-LinkType =" Absolute-path ">UpdateSourceEventName özellik değeri belirtebilirsiniz. Bu özellik, hedef özelliğin değiştiği zaman işaret eden yerel görünümdeki bir olayın adına ayarlanmalıdır. Ardından, yerel anahtarın değeri değiştiğinde, Binding sınıfa kullanıcının anahtar değerini değiştirdiği ve NativeSwitchPageViewModel.IsSwitchOn özellik değerinin güncelleştirildiği bildirilir.

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

Oluşturucu bağımsız değişkenleri, x:Arguments biçimlendirme uzantısı olan özniteliği kullanılarak yerel görünümlere geçirilebilir x:Static . Ayrıca, yerel görünüm Fabrika yöntemleri ( public static yöntemleri tanımlayan sınıf veya yapı ile aynı türdeki nesneleri veya değerleri döndüren yöntemler), özniteliği kullanılarak yöntemin adı x:FactoryMethod ve özniteliği kullanılarak bağımsız değişkenleri belirtilerek çağrılabilir x:Arguments .

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

<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.FromNameFactory yöntemi, UILabel.Font özelliği iOS üzerinde yeni bir olarak ayarlamak için kullanılır UIFont . UIFontAd ve boyut, özniteliğin alt öğesi olan yöntem bağımsız değişkenleriyle belirtilir x:Arguments .

Typeface.CreateFactory yöntemi, TextView.Typeface özelliği Android 'de yeni olarak ayarlamak için kullanılır Typeface . TypefaceAile adı ve stili, özniteliğinin alt öğesi olan yöntem bağımsız değişkenleriyle belirtilir x:Arguments .

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

Not

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

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

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 başvurun

özniteliği ile yerel bir görünüm adı vermek mümkün olmasa da x:Name , yerel görünümün bir ContentView öznitelik değerini belirten bir alt öğesi olması şartıyla, bir XAML dosyasında bir paylaşılan erişim Project arka plan kod dosyasından bir XAML dosyasında belirtilen yerel görünüm örneğini almak mümkündür x:Name . Ardından, arka plan kod dosyasındaki koşullu derleme yönergeleri içinde şunları yapmalısınız:

  1. "Data-LinkType =" Absolute-path ">özellik değerini _ContentView_Content Xamarin_Forms alın ContentView.Content ve platforma özgü bir NativeViewWrapper türe atayın.
  2. Özelliği alın NativeViewWrapper.NativeElement ve yerel görünüm türüne dönüştürün.

Yerel API daha sonra istenen işlemleri gerçekleştirmek için yerel görünümde çağrılabilir. Bu yaklaşım ayrıca, farklı platformlar için birden çok XAML yerel görünümünün aynı olması avantajını de sunmaktadır ContentView . Aşağıdaki kod örneği bu tekniği göstermektedir:

<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, ContentViewx:Name arka plan kodundaki öğesini almak için kullanılan öznitelik değeri ile denetimlerin alt öğesi ContentView .

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

Xamarin_Forms _ContentView_Content "Data-LinkType =" Absolute-path ">ContentView.Content özelliğine, sarmalanmış yerel görünümü platforma özgü bir örnek olarak almak için erişilir NativeViewWrapper . Bu NativeViewWrapper.NativeElement özelliğe daha sonra yerel görünümü yerel türü olarak almak için erişilir. Yerel görünümün API 'SI, istenen işlemleri gerçekleştirmek için çağrılır.

OnButtonTapHer yerel düğme EventHandler bir dokunma olayına yanıt olarak bir temsilci kullandığından IOS ve Android yerel düğmeleri aynı olay işleyicisini paylaşır. ancak, Evrensel Windows Platformu (UWP) ayrı bir kullanır RoutedEventHandler ve OnButtonTap bu örnekte olay işleyicisini de kullanır. Bu nedenle, yerel bir düğmeye tıklandığında OnButtonTap olay işleyicisi yürütülür ve bu, adlandırılmış yerel denetimi ölçeklendirir ve döndürür ContentViewcontentViewTextParent . Aşağıdaki ekran görüntüleri her platformda bu sorunun oluştuğunu göstermektedir:

Yerel denetim Içeren ContentView

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

Birçok iOS ve Android yerel görünümü XAML 'de örneklemeye uygun değildir çünkü denetimi ayarlamak için özellikler yerine yöntemler kullanır. Bu soruna yönelik çözüm, denetimin kurulumu için özellikleri kullanan ve platformdan bağımsız olayları kullanan daha XAML kullanımı kolay bir API tanımlayan sarmalayıcılardaki yerel görünümleri alt sınıflara vermektir. sarmalanan yerel görünümler daha sonra paylaşılan bir varlık Project (SAP) içine yerleştirilebilir ve koşullu derleme yönergeleri ile çevrelenebilir ya da platforma özel projelere yerleştirilebilir ve bir .NET Standard kitaplığı projesindeki XAML 'den başvuru yapılabilir.

Aşağıdaki kod örneği, alt Xamarin.Forms sınıflı yerel görünümleri tüketen bir 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>

Bu sayfa, Label Kullanıcı tarafından yerel bir denetimden seçilen meyve 'yi görüntüleyen bir içerir. LabelSubclassedNativeControlsPageViewModel.SelectedFruit Özelliğine bağlar. Xamarin_Forms _BindableObject_BindingContext "Data-LinkType =" Absolute-path ">, BindingContextSubclassedNativeControlsPageViewModel arabirimi uygulayan ViewModel sınıfıyla birlikte arka plan kod dosyasında sınıfının yeni bir örneğine ayarlanır INotifyPropertyChanged .

Bu sayfada her platform için yerel bir seçici görünümü de bulunur. Her yerel görünüm, özelliğini koleksiyona bağlayarak meyve 'nin koleksiyonunu görüntüler ItemSourceSubclassedNativeControlsPageViewModel.Fruits . Bu, kullanıcının aşağıdaki ekran görüntülerinde gösterildiği gibi bir meyve seçmesini sağlar:

Alt sınıflı yerel görünümler

İOS ve Android 'de yerel seçiciler, denetimleri ayarlamak için yöntemler kullanır. Bu nedenle, XAML 'yi kolay hale getirmek için özellikleri göstermek üzere bu seçiciler alt sınıflanmış olmalıdır. Evrensel Windows Platformu (UWP) üzerinde, ComboBox zaten XAML kullanımı kolay olduğundan, altsınıflama gerektirmez.

iOS

İOS uygulama görünümün alt sınıflarını UIPickerView oluşturur ve özellikleri ve xaml 'den kolayca tüketilebilen bir olay 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 { }
    }
}

MyUIPickerViewSınıfı ItemsSourceSelectedItem , ve özelliklerini ve bir olayını gösterir SelectedItemChanged . UIPickerViewUIPickerViewModel , Özellikler ve olay tarafından erişilen temel bir veri modeli gerektirir MyUIPickerView . UIPickerViewModelVeri modeli sınıfı tarafından sağlanır PickerModel :

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

PickerModelSınıfı MyUIPickerView , özelliği aracılığıyla sınıfı için temel depolamayı sağlar Items . Her seçili öğe MyUIPickerView değiştiğinde, Selected yöntemi yürütülür ve bu, seçili dizini güncelleştirir ve ItemChanged olayı tetikler. Bu, SelectedItem özelliğinin her zaman Kullanıcı tarafından çekilen son öğeyi döndürmesini sağlar. Ayrıca, PickerModel sınıfı örneği kurmak için kullanılan yöntemleri geçersiz kılar MyUIPickerView .

Android

Android uygulama görünümün alt sınıflarını Spinner oluşturur ve özellikleri ve xaml 'den kolayca tüketilebilen bir olay 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);
    }
}

MySpinnerSınıfı ItemsSourceSelectedObject , ve özelliklerini ve bir olayını gösterir ItemSelected . Sınıfı tarafından görüntülenen öğeler, MySpinnerAdapter görünüm ile ilişkili tarafından sağlanır ve öğeler AdapterItemsSource özellik ilk ayarlandığında öğesine doldurulur. Sınıftaki seçili öğe değiştiğinde MySpinner , OnBindableSpinnerItemSelected olay işleyicisi SelectedObject özelliği günceller.