Nativní zobrazení v jazyce XAML
Nativní zobrazení z iOSu, Androidu a Univerzální platforma Windows lze přímo odkazovat ze Xamarin.Forms souborů XAML. Vlastnosti a obslužné rutiny událostí lze nastavit v nativních zobrazeních a můžou pracovat se zobrazeními Xamarin.Forms . Tento článek ukazuje, jak využívat nativní zobrazení ze Xamarin.Forms souborů XAML.
Vložení nativního zobrazení do Xamarin.Forms souboru XAML:
xmlns
Přidejte deklaraci oboru názvů do souboru XAML pro obor názvů, který obsahuje nativní zobrazení.- Vytvořte instanci nativního zobrazení v souboru XAML.
Důležité
Zkompilovaný XAML musí být zakázán pro všechny stránky XAML, které používají nativní zobrazení. Toho lze dosáhnout dekorací třídy kódu pro vaši stránku XAML atributem [XamlCompilation(XamlCompilationOptions.Skip)]
. Další informace o kompilaci XAML naleznete v tématu Kompilace XAML v Xamarin.Forms.
Pokud chcete odkazovat na nativní zobrazení ze souboru kódu, musíte použít projekt sdíleného assetu (SAP) a zabalit kód specifický pro platformu direktivami podmíněné kompilace. Další informace naleznete v tématu Odkaz na nativní zobrazení z kódu.
Využívání nativních zobrazení
Následující příklad kódu ukazuje využití nativních zobrazení pro každou platformu Xamarin.FormsContentPage
na:
<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>
Stejně jako určení clr-namespace
a assembly
pro nativní obor názvů targetPlatform
zobrazení musí být také zadán. Toto nastavení by mělo být nastaveno na iOS
, , Android
, UWP
( Windows
které je ekvivalentní UWP
), macOS
, GTK
, Tizen
nebo WPF
. Analyzátor XAML bude za běhu ignorovat všechny předpony oboru názvů XML, které nemají targetPlatform
shodu s platformou, na které je aplikace spuštěná.
Každá deklarace oboru názvů se dá použít k odkazování na libovolnou třídu nebo strukturu ze zadaného oboru názvů. Deklarace oboru názvů lze například ios
použít k odkazování na libovolnou třídu nebo strukturu z oboru názvů iOS UIKit
. Vlastnosti nativního zobrazení lze nastavit prostřednictvím XAML, ale vlastnosti a typy objektů se musí shodovat. UILabel.TextColor
Například vlastnost je nastavena na UIColor.Red
použití x:Static
rozšíření značek a ios
oboru názvů.
Vlastnosti s možností vazby a připojené vlastnosti bindable lze také nastavit v nativních zobrazeních pomocí Class.BindableProperty="value"
syntaxe. Každé nativní zobrazení je zabaleno do instance specifické pro NativeViewWrapper
platformu, která je odvozena od Xamarin.Forms.View
třídy. Nastavení vlastnosti bindable nebo připojené bindable vlastnost v nativním zobrazení přenese hodnotu vlastnosti do obálky. Například vodorovné rozložení na střed lze určit nastavením View.HorizontalOptions="Center"
nativního zobrazení.
Poznámka:
Všimněte si, že styly nelze použít s nativními zobrazeními, protože styly můžou cílit pouze na vlastnosti, které jsou podporovány BindableProperty
objekty.
Konstruktory widgetu pro Android obecně vyžadují objekt Androidu Context
jako argument, který lze zpřístupnit prostřednictvím statické vlastnosti ve MainActivity
třídě. Proto při vytváření widgetu Android v XAML musí Context
být objekt obecně předán konstruktoru widgetu pomocí x:Arguments
atributu s rozšířením x:Static
značek. Další informace najdete v tématu Předání argumentů nativním zobrazením.
Poznámka:
Všimněte si, že pojmenování nativního zobrazení pomocí x:Name
není možné v projektu knihovny .NET Standard ani v projektu sdíleného assetu (SAP). Tím se vygeneruje proměnná nativního typu, která způsobí chybu kompilace. Nativní zobrazení se ale dají zabalit do ContentView
instancí a načíst do souboru kódu za předpokladu, že se používá SAP. Další informace naleznete v tématu Odkaz na nativní zobrazení z kódu.
Nativní vazby
Datová vazba se používá k synchronizaci uživatelského rozhraní se zdrojem dat a zjednodušuje zobrazení Xamarin.Forms a interakci s daty aplikace. Za předpokladuINotifyPropertyChanged
, že zdrojový objekt implementuje rozhraní, změny ve zdrojovém objektu se automaticky vloží do cílového objektu rozhraním vazby a změny v cílovém objektu lze volitelně odeslat do zdrojového objektu.
Vlastnosti nativních zobrazení můžou také používat datová vazba. Následující příklad kódu ukazuje datovou vazbu pomocí vlastností nativních zobrazení:
<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>
Stránka obsahuje vlastnost, jejíž Entry
IsEnabled
vlastnost je vázána na NativeSwitchPageViewModel.IsSwitchOn
vlastnost. Stránka BindingContext
je nastavena na novou instanci NativeSwitchPageViewModel
třídy v souboru kódu za, s ViewModel třídy implementuje INotifyPropertyChanged
rozhraní.
Stránka obsahuje také nativní přepínač pro každou platformu. Každý nativní přepínač používá TwoWay
vazbu k aktualizaci hodnoty NativeSwitchPageViewModel.IsSwitchOn
vlastnosti. Proto když je přepínač vypnutý, Entry
je zakázán a když je přepínač zapnutý, Entry
je povoleno. Následující snímky obrazovky znázorňují tuto funkci na jednotlivých platformách:
Obousměrné vazby jsou automaticky podporovány za předpokladu, že nativní vlastnost implementuje INotifyPropertyChanged
nebo podporuje funkci KVO (Key-Value Observing) v iOSu nebo je v DependencyProperty
UPW. Mnoho nativních zobrazení však nepodporuje oznámení o změně vlastnosti. Pro tato zobrazení můžete jako součást vazbového výrazu zadat UpdateSourceEventName
hodnotu vlastnosti. Tato vlastnost by měla být nastavena na název události v nativním zobrazení, který signalizuje, když se cílová vlastnost změnila. Když se pak změní hodnota nativního přepínače, Binding
třída je upozorněna, že uživatel změnil hodnotu přepínače a NativeSwitchPageViewModel.IsSwitchOn
hodnota vlastnosti se aktualizuje.
Předání argumentů nativním zobrazením
Argumenty konstruktoru lze předat nativním zobrazením pomocí x:Arguments
atributu s rozšířením x:Static
značek. Kromě toho lze nativní metody objektu pro zobrazení (public static
metody, které vracejí objekty nebo hodnoty stejného typu jako třída nebo struktura definující metody) volat zadáním názvu metody pomocí atributu x:FactoryMethod
a jeho argumenty pomocí atributu x:Arguments
.
Následující příklad kódu ukazuje obě techniky:
<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>
Metoda UIFont.FromName
továrny se používá k nastavení UILabel.Font
vlastnosti na novou UIFont
v iOSu. Název UIFont
a velikost jsou určeny argumenty metody, které jsou podřízené atributu x:Arguments
.
Metoda Typeface.Create
továrny se používá k nastavení TextView.Typeface
vlastnosti na nový Typeface
v Androidu. Název Typeface
a styl rodiny jsou určeny argumenty metody, které jsou podřízené atributu x:Arguments
.
Konstruktor FontFamily
slouží k nastavení TextBlock.FontFamily
vlastnosti na novou FontFamily
v Univerzální platforma Windows (UPW). Název FontFamily
je určen argumentem metody, který je podřízený atribut.x:Arguments
Poznámka:
Argumenty musí odpovídat typům požadovaným konstruktorem nebo metodou továrny.
Následující snímky obrazovky ukazují výsledek zadání argumentů metody továrny a konstruktoru pro nastavení písma v různých nativních zobrazeních:
Další informace o předávání argumentů v XAML naleznete v tématu Předávání argumentů v XAML.
Odkaz na nativní zobrazení z kódu
I když není možné pojmenovat nativní zobrazení pomocí atributu x:Name
, je možné načíst instanci nativního zobrazení deklarovanou v souboru XAML ze souboru kódu v projektu sdíleného přístupu za předpokladu, že nativní zobrazení je podřízeným objektem ContentView
, který určuje x:Name
hodnotu atributu. Pak uvnitř direktiv podmíněné kompilace v souboru s kódem byste měli:
ContentView.Content
Načtěte hodnotu vlastnosti a přetypujte ji na typ specifický proNativeViewWrapper
platformu.NativeViewWrapper.NativeElement
Načtěte vlastnost a přetypujte ji na nativní typ zobrazení.
Nativní rozhraní API se pak dá vyvolat v nativním zobrazení a provést požadované operace. Tento přístup také nabízí výhodu, že více nativních zobrazení XAML pro různé platformy může být podřízené stejné ContentView
. Následující příklad kódu ukazuje tuto techniku:
<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>
V předchozím příkladu jsou nativní zobrazení pro každou platformu podřízenými ContentView
ovládacími prvky s x:Name
hodnotou atributu, která se používá k načtení ContentView
v kódu na pozadí:
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;
}
}
Vlastnost ContentView.Content
je přístupná k načtení zabaleného nativního zobrazení jako instance specifické pro NativeViewWrapper
platformu. K NativeViewWrapper.NativeElement
této vlastnosti se pak přistupuje k načtení nativního zobrazení jako jeho nativního typu. Rozhraní API nativního zobrazení se pak vyvolá za účelem provedení požadovaných operací.
Nativní tlačítka pro iOS a Android sdílejí stejnou obslužnou OnButtonTap
rutinu události, protože každé nativní tlačítko využívá EventHandler
delegáta v reakci na dotykovou událost. Nicméně Univerzální platforma Windows (UPW) používá samostatnou RoutedEventHandler
, která zase využívá obslužnou rutinu OnButtonTap
události v tomto příkladu. Proto se při kliknutí na OnButtonTap
nativní tlačítko spustí obslužná rutina události, která škáluje a otočí nativní ovládací prvek obsažený v pojmenovaném ContentView
contentViewTextParent
. Následující snímky obrazovky ukazují, že k tomu dochází na jednotlivých platformách:
Nativní zobrazení podtřídy
Mnoho nativních zobrazení pro iOS a Android není vhodné pro vytvoření instance v jazyce XAML, protože k nastavení ovládacího prvku používají metody, nikoli vlastnosti. Řešením tohoto problému je podtřída nativních zobrazení v obálkách, které definují popisnější rozhraní API XAML, které používá vlastnosti k nastavení ovládacího prvku a které používají události nezávislé na platformě. Zabalená nativní zobrazení se pak dají umístit do projektu sdíleného assetu (SAP) a být obklopena direktivami podmíněné kompilace nebo umístěná v projektech specifických pro platformu a odkazovaná z XAML v projektu knihovny .NET Standard.
Následující příklad kódu ukazuje Xamarin.Forms stránku, která využívá podtřídě nativní zobrazení:
<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>
Stránka obsahuje Label
ovoce vybrané uživatelem z nativního ovládacího prvku. Vazby Label
na SubclassedNativeControlsPageViewModel.SelectedFruit
vlastnost. Stránka BindingContext
je nastavena na novou instanci SubclassedNativeControlsPageViewModel
třídy v souboru kódu za, s ViewModel třídy implementuje INotifyPropertyChanged
rozhraní.
Stránka obsahuje také nativní zobrazení pro výběr pro každou platformu. Každé nativní zobrazení zobrazí kolekci ovoce vazbou jeho ItemSource
vlastnosti na kolekci SubclassedNativeControlsPageViewModel.Fruits
. To uživateli umožňuje vybrat ovoce, jak je znázorněno na následujících snímcích obrazovky:
V iOSu a Androidu používají nativní výběrové metody k nastavení ovládacích prvků. Proto musí být tyto nástroje pro výběr podtříděny, aby byly vystaveny vlastnosti, aby byly přívětivé pro XAML. U Univerzální platforma Windows (UPW) ComboBox
je už přívětivý pro XAML, takže nevyžaduje podtřídy.
iOS
Implementace iOS podtřídy UIPickerView
zobrazení a zveřejňuje vlastnosti a událost, kterou lze snadno využívat z XAML:
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 { }
}
}
Třída MyUIPickerView
zveřejňuje ItemsSource
a SelectedItem
vlastnosti a SelectedItemChanged
událost. A UIPickerView
vyžaduje podkladový UIPickerViewModel
datový model, ke kterému MyUIPickerView
přistupuje vlastnosti a událost. Datový UIPickerViewModel
model poskytuje PickerModel
třída:
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());
}
}
}
Třída PickerModel
poskytuje podkladové úložiště pro MyUIPickerView
třídu prostřednictvím Items
vlastnosti. Pokaždé, když se vybraná položka ve MyUIPickerView
změnách provede, Selected
spustí se metoda, která aktualizuje vybraný index a aktivuje ItemChanged
událost. Tím se zajistí, že SelectedItem
vlastnost vždy vrátí poslední položku, kterou vybral uživatel. Kromě toho PickerModel
třída přepisuje metody, které se používají k nastavení MyUIPickerView
instance.
Android
Implementace Androidu Spinner
podtřídy zobrazení a zveřejňuje vlastnosti a událost, kterou lze snadno využívat z XAML:
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);
}
}
Třída MySpinner
zveřejňuje ItemsSource
a SelectedObject
vlastnosti a ItemSelected
událost. Položky zobrazené MySpinner
třídou jsou poskytovány Adapter
přidruženým k zobrazení a položky jsou naplněny do Adapter
při ItemsSource
prvním nastavení vlastnosti. Kdykoli se vybraná položka ve MySpinner
třídě změní, obslužná rutina OnBindableSpinnerItemSelected
události aktualizuje SelectedObject
vlastnost.