Bölüm 5. Veri Bağlamaları - MVVM
Model-View-ViewModel (MVVM) mimari deseni XAML düşünülerek icat edilmiştir. Desen üç yazılım katmanı arasında ayrım uygular: Görünüm olarak adlandırılan XAML kullanıcı arabirimi; Model olarak adlandırılan temel alınan veriler; ve Görünüm ile Model arasında ViewModel adlı bir aracı. View ve ViewModel genellikle XAML dosyasında tanımlanan veri bağlamaları aracılığıyla bağlanır. Görünüm için BindingContext genellikle ViewModel'in bir örneğidir.
Basit Bir ViewModel
ViewModels'e giriş olarak, ilk olarak bir program olmadan bir programa göz atalım.
Daha önce, bir XAML dosyasının diğer derlemelerdeki sınıflara başvurmasına izin vermek için yeni bir XML ad alanı bildirimi tanımlamayı gördünüz. Ad alanı için xml ad alanı bildirimini tanımlayan bir program aşağıdadır System
:
xmlns:sys="clr-namespace:System;assembly=netstandard"
Program, statik DateTime.Now
özelliğinden geçerli tarih ve saati almak ve bu DateTime
değeri üzerinde StackLayout
olarak ayarlamak için BindingContext
kullanabilirx:Static
:
<StackLayout BindingContext="{x:Static sys:DateTime.Now}" …>
BindingContext
özel bir özelliktir: öğesini ayarladığınızda BindingContext
, bu öğenin tüm alt öğeleri tarafından devralınır. Bu, öğesinin tüm alt öğelerinin StackLayout
aynı BindingContext
olduğu ve bu nesnenin özelliklerine yönelik basit bağlamalar içerebileceği anlamına gelir.
One-Shot DateTime programında, alt öğelerden ikisi bu DateTime
değerin özelliklerine bağlamalar içerir, ancak diğer iki alt öğe bağlama yolu eksik gibi görünen bağlamalar içerir. Bu, değerin DateTime
kendisi için StringFormat
kullanıldığı anlamına gelir:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="XamlSamples.OneShotDateTimePage"
Title="One-Shot DateTime Page">
<StackLayout BindingContext="{x:Static sys:DateTime.Now}"
HorizontalOptions="Center"
VerticalOptions="Center">
<Label Text="{Binding Year, StringFormat='The year is {0}'}" />
<Label Text="{Binding StringFormat='The month is {0:MMMM}'}" />
<Label Text="{Binding Day, StringFormat='The day is {0}'}" />
<Label Text="{Binding StringFormat='The time is {0:T}'}" />
</StackLayout>
</ContentPage>
Sorun, sayfa ilk oluşturulduğunda tarih ve saatin bir kez ayarlanması ve hiçbir zaman değişmemiş olmasıdır:
XAML dosyası her zaman geçerli saati gösteren bir saat görüntüleyebilir, ancak yardımcı olması için koda ihtiyacı vardır. MVVM açısından düşünürken Model ve ViewModel tamamen kodla yazılmış sınıflardır. Görünüm genellikle veri bağlamaları aracılığıyla ViewModel'de tanımlanan özelliklere başvuran bir XAML dosyasıdır.
Düzgün bir Model ViewModel'i bilmez ve uygun bir ViewModel de Görünüm'ü bilmez. Ancak, bir programcı genellikle ViewModel tarafından kullanıma sunulan veri türlerini belirli kullanıcı arabirimleriyle ilişkili veri türlerine göre uyarlar. Örneğin, model 8 bit karakterli ASCII dizeleri içeren bir veritabanına erişiyorsa, ViewModel'in kullanıcı arabiriminde Özel Unicode kullanımına uyum sağlamak için bu dizeler arasında Unicode dizelerine dönüştürmesi gerekir.
MVVM'nin basit örneklerinde (burada gösterilenler gibi), genellikle Model yoktur ve desen yalnızca veri bağlamalarıyla bağlantılı bir View ve ViewModel içerir.
Bu özelliği her saniye güncelleştiren DateTime
adlı DateTime
tek bir özelliğe sahip saat için bir ViewModel aşağıda verilmiştir:
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace XamlSamples
{
class ClockViewModel : INotifyPropertyChanged
{
DateTime dateTime;
public event PropertyChangedEventHandler PropertyChanged;
public ClockViewModel()
{
this.DateTime = DateTime.Now;
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
this.DateTime = DateTime.Now;
return true;
});
}
public DateTime DateTime
{
set
{
if (dateTime != value)
{
dateTime = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("DateTime"));
}
}
}
get
{
return dateTime;
}
}
}
}
ViewModel'ler genellikle arabirimini INotifyPropertyChanged
uygular; bu da sınıfının özelliklerinden biri değiştiğinde bir PropertyChanged
olay tetiklediği anlamına gelir. içindeki veri bağlama mekanizması, bir özellik değiştiğinde Xamarin.Forms bildirim almak ve hedefi yeni değerle güncel tutmak için bu PropertyChanged
olaya bir işleyici ekler.
Bu ViewModel'i temel alan bir saat aşağıdaki kadar basit olabilir:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
x:Class="XamlSamples.ClockPage"
Title="Clock Page">
<Label Text="{Binding DateTime, StringFormat='{0:T}'}"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center">
<Label.BindingContext>
<local:ClockViewModel />
</Label.BindingContext>
</Label>
</ContentPage>
öğesinin ClockViewModel
using özellik öğesi etiketlerinin değerine nasıl ayarlandığına BindingContext
Label
dikkat edin. Alternatif olarak, bir koleksiyonda örneğini ClockViewModel
oluşturabilir ve bir StaticResource
işaretleme uzantısı aracılığıyla değerine ayarlayabilirsinizBindingContext
.Resources
Veya arka planda kod dosyası ViewModel örneğini oluşturabilir.
Binding
özelliğindeki Text
Label
işaretleme uzantısı özelliği biçimlendirmektedirDateTime
. Ekran şu şekildedir:
Özellikleri noktalarla ayırarak ViewModel özelliğinin tek tek DateTime
özelliklerine de erişmek mümkündür:
<Label Text="{Binding DateTime.Second, StringFormat='{0}'}" … >
Etkileşimli MVVM
MVVM genellikle temel alınan veri modelini temel alan etkileşimli bir görünüm için iki yönlü veri bağlamalarıyla birlikte kullanılır.
Burada, bir değeri , Saturation
ve Luminosity
değerlerine Hue
dönüştüren adlı HslViewModel
bir Color
sınıf verilmiştir ve bunun tersi de geçerlidir:
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace XamlSamples
{
public class HslViewModel : INotifyPropertyChanged
{
double hue, saturation, luminosity;
Color color;
public event PropertyChangedEventHandler PropertyChanged;
public double Hue
{
set
{
if (hue != value)
{
hue = value;
OnPropertyChanged("Hue");
SetNewColor();
}
}
get
{
return hue;
}
}
public double Saturation
{
set
{
if (saturation != value)
{
saturation = value;
OnPropertyChanged("Saturation");
SetNewColor();
}
}
get
{
return saturation;
}
}
public double Luminosity
{
set
{
if (luminosity != value)
{
luminosity = value;
OnPropertyChanged("Luminosity");
SetNewColor();
}
}
get
{
return luminosity;
}
}
public Color Color
{
set
{
if (color != value)
{
color = value;
OnPropertyChanged("Color");
Hue = value.Hue;
Saturation = value.Saturation;
Luminosity = value.Luminosity;
}
}
get
{
return color;
}
}
void SetNewColor()
{
Color = Color.FromHsla(Hue, Saturation, Luminosity);
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
, Saturation
ve özelliklerinde yapılan değişiklikler özelliğin Hue
Color
değişmesine, değişiklikleri Color
ise diğer üç özelliğin değişmesine neden Luminosity
olur. Bu, özelliği değişmediği sürece sınıfın olayı çağırmaması PropertyChanged
dışında sonsuz bir döngü gibi görünebilir. Bu, aksi takdirde kontrol edilemeyen geri bildirim döngüsüne son verir.
Aşağıdaki XAML dosyası, özelliği ViewModel'in özelliğine Color
bağlı olan Color
bir BoxView
ve , Saturation
ve özelliklerine Hue
bağlı üç Slider
ve Luminosity
üç Label
görünümü içerir:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
x:Class="XamlSamples.HslColorScrollPage"
Title="HSL Color Scroll Page">
<ContentPage.BindingContext>
<local:HslViewModel Color="Aqua" />
</ContentPage.BindingContext>
<StackLayout Padding="10, 0">
<BoxView Color="{Binding Color}"
VerticalOptions="FillAndExpand" />
<Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}"
HorizontalOptions="Center" />
<Slider Value="{Binding Hue, Mode=TwoWay}" />
<Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}"
HorizontalOptions="Center" />
<Slider Value="{Binding Saturation, Mode=TwoWay}" />
<Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}"
HorizontalOptions="Center" />
<Slider Value="{Binding Luminosity, Mode=TwoWay}" />
</StackLayout>
</ContentPage>
Her Label
bir üzerindeki bağlama varsayılandır OneWay
. Yalnızca değeri görüntülemesi gerekir. Ancak her Slider
birinin bağlaması şeklindedir TwoWay
. Bu, öğesinin Slider
ViewModel'den başlatılmasını sağlar. Özelliğin Color
ViewModel örneği oluşturulurken olarak ayarlandığına Aqua
dikkat edin. Ancak içindeki bir değişikliğin Slider
ViewModel'de özelliği için yeni bir değer ayarlaması gerekir ve bu da yeni bir renk hesaplar.
ViewModels ile komut oluşturma
Çoğu durumda, MVVM deseni veri öğelerinin işlemesi ile sınırlıdır: ViewModel'deki Paralel veri nesnelerini görüntüle'deki kullanıcı arabirimi nesneleri.
Ancak, bazen Görünüm'de ViewModel'de çeşitli eylemleri tetikleyen düğmeler olması gerekir. Ancak ViewModel, viewmodel'i belirli bir kullanıcı arabirimi paradigmasıyla ilişkilendireceğinden düğmeler için işleyiciler içermemelidir Clicked
.
ViewModel'lerin belirli kullanıcı arabirimi nesnelerinden daha bağımsız olmasına ancak yine de ViewModel içinde yöntemlerin çağrılmasına izin vermek için bir komut arabirimi vardır. Bu komut arabirimi, içindeki Xamarin.Formsaşağıdaki öğeler tarafından desteklenir:
Button
MenuItem
ToolbarItem
SearchBar
TextCell
(ve bu nedenle deImageCell
)ListView
TapGestureRecognizer
ve ListView
öğesi dışındaSearchBar
, bu öğeler iki özellik tanımlar:
Command
türüSystem.Windows.Input.ICommand
CommandParameter
türüObject
SearchBar
türündeki ICommand
bir RefreshCommand
özelliği tanımlarken ListView
SearchCommand
ve SearchCommandParameter
özelliklerini tanımlar.
ICommand
Arabirimi iki yöntem ve bir olay tanımlar:
void Execute(object arg)
bool CanExecute(object arg)
event EventHandler CanExecuteChanged
ViewModel türündeki ICommand
özellikleri tanımlayabilir. Daha sonra bu özellikleri her Button
birinin veya başka bir öğenin özelliğine Command
ya da bu arabirimi uygulayan özel bir görünüme bağlayabilirsiniz. İsteğe bağlı olarak, bu ViewModel özelliğine bağlı nesneleri Button
(veya diğer öğeleri) tanımlamak için özelliğini ayarlayabilirsinizCommandParameter
. dahili olarak, Button
kullanıcı öğesine dokunduğunda Button
yöntemini çağırır Execute
ve yöntemine Execute
iletirCommandParameter
.
Yöntem CanExecute
ve CanExecuteChanged
olay, bir Button
dokunmanın şu anda geçersiz olabileceği durumlarda kullanılır ve bu durumda Button
kendisi devre dışı bırakılmalıdır. Button
özelliği ilk ayarlandığında ve CanExecuteChanged
olay tetiklendiğinde çağrılar CanExecute
Command
. döndürürsefalse
CanExecute
, Button
kendisini devre dışı bırakır ve çağrı oluşturmazExecute
.
ViewModel'lerinize komut ekleme konusunda yardım almak için, Xamarin.Forms öğesini uygulayan ICommand
iki sınıf tanımlar ve Command<T>
burada T
ve CanExecute
bağımsız değişkenlerinin Execute
türüdürCommand
. Bu iki sınıf, birkaç oluşturucunun yanı sıra ViewModel'in nesneyi olayı tetiklemeye CanExecuteChanged
zorlamak Command
için çağırabileceği bir ChangeCanExecute
yöntem tanımlar.
Burada, telefon numaralarını girmeye yönelik basit bir tuş takımına yönelik bir ViewModel bulunur. ve CanExecute
yönteminin Execute
doğrudan oluşturucuda lambda işlevleri olarak tanımlandığına dikkat edin:
using System;
using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;
namespace XamlSamples
{
class KeypadViewModel : INotifyPropertyChanged
{
string inputString = "";
string displayText = "";
char[] specialChars = { '*', '#' };
public event PropertyChangedEventHandler PropertyChanged;
// Constructor
public KeypadViewModel()
{
AddCharCommand = new Command<string>((key) =>
{
// Add the key to the input string.
InputString += key;
});
DeleteCharCommand = new Command(() =>
{
// Strip a character from the input string.
InputString = InputString.Substring(0, InputString.Length - 1);
},
() =>
{
// Return true if there's something to delete.
return InputString.Length > 0;
});
}
// Public properties
public string InputString
{
protected set
{
if (inputString != value)
{
inputString = value;
OnPropertyChanged("InputString");
DisplayText = FormatText(inputString);
// Perhaps the delete button must be enabled/disabled.
((Command)DeleteCharCommand).ChangeCanExecute();
}
}
get { return inputString; }
}
public string DisplayText
{
protected set
{
if (displayText != value)
{
displayText = value;
OnPropertyChanged("DisplayText");
}
}
get { return displayText; }
}
// ICommand implementations
public ICommand AddCharCommand { protected set; get; }
public ICommand DeleteCharCommand { protected set; get; }
string FormatText(string str)
{
bool hasNonNumbers = str.IndexOfAny(specialChars) != -1;
string formatted = str;
if (hasNonNumbers || str.Length < 4 || str.Length > 10)
{
}
else if (str.Length < 8)
{
formatted = String.Format("{0}-{1}",
str.Substring(0, 3),
str.Substring(3));
}
else
{
formatted = String.Format("({0}) {1}-{2}",
str.Substring(0, 3),
str.Substring(3, 3),
str.Substring(6));
}
return formatted;
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Bu ViewModel, özelliğinin AddCharCommand
her biri tarafından tanımlanan birkaç düğmenin (veya komut arabirimi olan başka bir şeyin) özelliğine CommandParameter
bağlı Command
olduğunu varsayar. Bu düğmeler bir özelliğe karakter InputString
ekler ve bu da özellik için DisplayText
telefon numarası olarak biçimlendirilir.
ayrıca adlı DeleteCharCommand
türünün ICommand
ikinci bir özelliği de vardır. Bu, bir geri aralığı düğmesine bağlıdır, ancak silinecek karakter yoksa düğme devre dışı bırakılmalıdır.
Aşağıdaki tuş takımı görsel olarak olabildiğince karmaşık değildir. Bunun yerine, komut arabiriminin kullanımını daha net bir şekilde göstermek için işaretleme en aza indirilmiştir:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
x:Class="XamlSamples.KeypadPage"
Title="Keypad Page">
<Grid HorizontalOptions="Center"
VerticalOptions="Center">
<Grid.BindingContext>
<local:KeypadViewModel />
</Grid.BindingContext>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<!-- Internal Grid for top row of items -->
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Frame Grid.Column="0"
OutlineColor="Accent">
<Label Text="{Binding DisplayText}" />
</Frame>
<Button Text="⇦"
Command="{Binding DeleteCharCommand}"
Grid.Column="1"
BorderWidth="0" />
</Grid>
<Button Text="1"
Command="{Binding AddCharCommand}"
CommandParameter="1"
Grid.Row="1" Grid.Column="0" />
<Button Text="2"
Command="{Binding AddCharCommand}"
CommandParameter="2"
Grid.Row="1" Grid.Column="1" />
<Button Text="3"
Command="{Binding AddCharCommand}"
CommandParameter="3"
Grid.Row="1" Grid.Column="2" />
<Button Text="4"
Command="{Binding AddCharCommand}"
CommandParameter="4"
Grid.Row="2" Grid.Column="0" />
<Button Text="5"
Command="{Binding AddCharCommand}"
CommandParameter="5"
Grid.Row="2" Grid.Column="1" />
<Button Text="6"
Command="{Binding AddCharCommand}"
CommandParameter="6"
Grid.Row="2" Grid.Column="2" />
<Button Text="7"
Command="{Binding AddCharCommand}"
CommandParameter="7"
Grid.Row="3" Grid.Column="0" />
<Button Text="8"
Command="{Binding AddCharCommand}"
CommandParameter="8"
Grid.Row="3" Grid.Column="1" />
<Button Text="9"
Command="{Binding AddCharCommand}"
CommandParameter="9"
Grid.Row="3" Grid.Column="2" />
<Button Text="*"
Command="{Binding AddCharCommand}"
CommandParameter="*"
Grid.Row="4" Grid.Column="0" />
<Button Text="0"
Command="{Binding AddCharCommand}"
CommandParameter="0"
Grid.Row="4" Grid.Column="1" />
<Button Text="#"
Command="{Binding AddCharCommand}"
CommandParameter="#"
Grid.Row="4" Grid.Column="2" />
</Grid>
</ContentPage>
Command
Bu işaretlemede görüntülenen ilk Button
öğesinin özelliği öğesine bağlıdırDeleteCharCommand
; geri kalanıAddCharCommand
, yüzde görünen Button
karakterle aynı olan ile CommandParameter
ilişkilidir. İşte program şu şekildedir:
Zaman Uyumsuz Yöntemleri Çağırma
Komutlar zaman uyumsuz yöntemleri de çağırabilir. Bu, yöntemini belirtirken ve await
anahtar sözcükleri kullanılarak async
elde edilirExecute
:
DownloadCommand = new Command (async () => await DownloadAsync ());
Bu, yönteminin DownloadAsync
bir Task
olduğunu ve beklenmesi gerektiğini gösterir:
async Task DownloadAsync ()
{
await Task.Run (() => Download ());
}
void Download ()
{
...
}
Gezinti Menüsü Uygulama
Bu makale serisindeki tüm kaynak kodunu içeren örnek program, giriş sayfası için bir ViewModel kullanır. Bu ViewModel, adlı Type
Title
üç özelliğe sahip ve Description
örnek sayfaların her birinin türünü, bir başlığı ve kısa bir açıklamayı içeren kısa bir sınıfın tanımıdır. Ayrıca ViewModel, programdaki tüm sayfaların koleksiyonu olan adlı All
statik özelliği tanımlar:
public class PageDataViewModel
{
public PageDataViewModel(Type type, string title, string description)
{
Type = type;
Title = title;
Description = description;
}
public Type Type { private set; get; }
public string Title { private set; get; }
public string Description { private set; get; }
static PageDataViewModel()
{
All = new List<PageDataViewModel>
{
// Part 1. Getting Started with XAML
new PageDataViewModel(typeof(HelloXamlPage), "Hello, XAML",
"Display a Label with many properties set"),
new PageDataViewModel(typeof(XamlPlusCodePage), "XAML + Code",
"Interact with a Slider and Button"),
// Part 2. Essential XAML Syntax
new PageDataViewModel(typeof(GridDemoPage), "Grid Demo",
"Explore XAML syntax with the Grid"),
new PageDataViewModel(typeof(AbsoluteDemoPage), "Absolute Demo",
"Explore XAML syntax with AbsoluteLayout"),
// Part 3. XAML Markup Extensions
new PageDataViewModel(typeof(SharedResourcesPage), "Shared Resources",
"Using resource dictionaries to share resources"),
new PageDataViewModel(typeof(StaticConstantsPage), "Static Constants",
"Using the x:Static markup extensions"),
new PageDataViewModel(typeof(RelativeLayoutPage), "Relative Layout",
"Explore XAML markup extensions"),
// Part 4. Data Binding Basics
new PageDataViewModel(typeof(SliderBindingsPage), "Slider Bindings",
"Bind properties of two views on the page"),
new PageDataViewModel(typeof(SliderTransformsPage), "Slider Transforms",
"Use Sliders with reverse bindings"),
new PageDataViewModel(typeof(ListViewDemoPage), "ListView Demo",
"Use a ListView with data bindings"),
// Part 5. From Data Bindings to MVVM
new PageDataViewModel(typeof(OneShotDateTimePage), "One-Shot DateTime",
"Obtain the current DateTime and display it"),
new PageDataViewModel(typeof(ClockPage), "Clock",
"Dynamically display the current time"),
new PageDataViewModel(typeof(HslColorScrollPage), "HSL Color Scroll",
"Use a view model to select HSL colors"),
new PageDataViewModel(typeof(KeypadPage), "Keypad",
"Use a view model for numeric keypad logic")
};
}
public static IList<PageDataViewModel> All { private set; get; }
}
için MainPage
XAML dosyası, özelliği bu All
özelliğe ayarlanmış olan ve her sayfanın ve Description
özelliklerini görüntülemek Title
için bir içeren bir TextCell
öğesini tanımlar ListBox
ItemsSource
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples"
x:Class="XamlSamples.MainPage"
Padding="5, 0"
Title="XAML Samples">
<ListView ItemsSource="{x:Static local:PageDataViewModel.All}"
ItemSelected="OnListViewItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}"
Detail="{Binding Description}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
Sayfalar kaydırılabilir bir listede gösterilir:
Kullanıcı bir öğe seçtiğinde arka planda kod dosyasındaki işleyici tetikleniyor. İşleyici, back null
özelliğini ListBox
olarak ayarlar SelectedItem
ve ardından seçili sayfayı örnekleyip bu sayfaya gider:
private async void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs args)
{
(sender as ListView).SelectedItem = null;
if (args.SelectedItem != null)
{
PageDataViewModel pageData = args.SelectedItem as PageDataViewModel;
Page page = (Page)Activator.CreateInstance(pageData.Type);
await Navigation.PushAsync(page);
}
}
Video
Xamarin Evolve 2016: MVVM Made Simple with Xamarin.Forms and Prism
Özet
XAML, özellikle veri bağlama ve MVVM kullanıldığında uygulamalarda kullanıcı arabirimlerini Xamarin.Forms tanımlamaya yönelik güçlü bir araçtır. Sonuç, kodda tüm arka plan desteğine sahip bir kullanıcı arabiriminin temiz, zarif ve potansiyel olarak araçlanabilir bir gösterimidir.
İlişkili Bağlantılar
- Bölüm 1. XAML Kullanmaya Başlarken
- Bölüm 2. Temel XAML Söz Dizimi
- Bölüm 3. XAML Biçimlendirme Uzantıları
- Bölüm 4. Temel Veri Bağlama Bilgileri
İlgili Videolar
Channel 9 ve YouTube'da daha fazla Xamarin videosu bulun.