Přizpůsobení buňky ViewCell
Xamarin.Forms ViewCell je buňka, kterou lze přidat do ListView nebo TableView, která obsahuje zobrazení definované vývojářem. Tento článek ukazuje, jak vytvořit vlastní renderer pro ViewCell hostovaný uvnitř Xamarin.Forms ListView ovládacího prvku. Tím se při Xamarin.Forms posouvání ListView opakovaně nevolají výpočty rozložení.
Každá Xamarin.Forms buňka má doprovodný renderer pro každou platformu, která vytvoří instanci nativního ovládacího prvku. ViewCell
Při vykreslení Xamarin.Forms aplikací se v iOSu ViewCellRenderer
vytvoří instance třídy, která následně vytvoří instanci nativního UITableViewCell
ovládacího prvku. Na platformě Android třída ViewCellRenderer
vytvoří instanci nativního View
ovládacího prvku. V Univerzální platforma Windows (UPW) třída ViewCellRenderer
vytvoří instanci nativní DataTemplate
. Další informace o rendereru a nativních tříd ovládacích prvcích, které Xamarin.Forms řídí mapování, naleznete v tématu Renderer Základní třídy a nativní ovládací prvky.
Následující diagram znázorňuje vztah mezi ViewCell
a odpovídajícími nativními ovládacími prvky, které ho implementují:
Proces vykreslování můžete využít k implementaci přizpůsobení specifických pro platformu vytvořením vlastního rendereru pro každou platformu ViewCell
. Postup je následující:
- Vytvořte vlastní buňku Xamarin.Forms .
- Spotřebujte vlastní buňku z Xamarin.Formsbuňky .
- Vytvořte vlastní renderer pro buňku na každé platformě.
Jednotlivé položky se teď probírají a implementují NativeCell
renderer, který využívá rozložení specifické pro platformu pro každou buňku Xamarin.FormsListView
hostovanou uvnitř ovládacího prvku. Tím se zastaví Xamarin.Forms opakované vyvolání výpočtů rozložení během ListView
posouvání.
Vytvoření vlastní buňky
Vlastní ovládací prvek buňky lze vytvořit podtřídou ViewCell
třídy, jak je znázorněno v následujícím příkladu kódu:
public class NativeCell : ViewCell
{
public static readonly BindableProperty NameProperty =
BindableProperty.Create ("Name", typeof(string), typeof(NativeCell), "");
public string Name {
get { return (string)GetValue (NameProperty); }
set { SetValue (NameProperty, value); }
}
public static readonly BindableProperty CategoryProperty =
BindableProperty.Create ("Category", typeof(string), typeof(NativeCell), "");
public string Category {
get { return (string)GetValue (CategoryProperty); }
set { SetValue (CategoryProperty, value); }
}
public static readonly BindableProperty ImageFilenameProperty =
BindableProperty.Create ("ImageFilename", typeof(string), typeof(NativeCell), "");
public string ImageFilename {
get { return (string)GetValue (ImageFilenameProperty); }
set { SetValue (ImageFilenameProperty, value); }
}
}
Třída NativeCell
se vytvoří v projektu knihovny .NET Standard a definuje rozhraní API pro vlastní buňku. Vlastní buňka zveřejňuje Name
Category
vlastnosti a ImageFilename
vlastnosti, které lze zobrazit prostřednictvím datové vazby. Další informace o datové vazbě najdete v tématu Základy datových vazeb.
Využívání vlastní buňky
Na NativeCell
vlastní buňku lze odkazovat v kódu Xaml v projektu knihovny .NET Standard deklarováním oboru názvů pro jeho umístění a použitím předpony oboru názvů ve vlastním prvku buňky. Následující příklad kódu ukazuje, jak NativeCell
lze vlastní buňku využívat stránkou XAML:
<ContentPage ...
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
...>
...
<ContentPage.Content>
<StackLayout>
<Label Text="Xamarin.Forms native cell" HorizontalTextAlignment="Center" />
<ListView x:Name="listView" CachingStrategy="RecycleElement" ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<local:NativeCell Name="{Binding Name}" Category="{Binding Category}" ImageFilename="{Binding ImageFilename}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Předponu local
oboru názvů lze pojmenovat cokoli. clr-namespace
Hodnoty ale assembly
musí odpovídat podrobnostem vlastního ovládacího prvku. Jakmile je obor názvů deklarován, předpona se použije k odkazování na vlastní buňku.
Následující příklad kódu ukazuje, jak NativeCell
lze vlastní buňku využívat na stránce jazyka C#:
public class NativeCellPageCS : ContentPage
{
ListView listView;
public NativeCellPageCS()
{
listView = new ListView(ListViewCachingStrategy.RecycleElement)
{
ItemsSource = DataSource.GetList(),
ItemTemplate = new DataTemplate(() =>
{
var nativeCell = new NativeCell();
nativeCell.SetBinding(NativeCell.NameProperty, "Name");
nativeCell.SetBinding(NativeCell.CategoryProperty, "Category");
nativeCell.SetBinding(NativeCell.ImageFilenameProperty, "ImageFilename");
return nativeCell;
})
};
switch (Device.RuntimePlatform)
{
case Device.iOS:
Padding = new Thickness(0, 20, 0, 0);
break;
case Device.Android:
case Device.UWP:
Padding = new Thickness(0);
break;
}
Content = new StackLayout
{
Children = {
new Label { Text = "Xamarin.Forms native cell", HorizontalTextAlignment = TextAlignment.Center },
listView
}
};
listView.ItemSelected += OnItemSelected;
}
...
}
Ovládací Xamarin.FormsListView
prvek slouží k zobrazení seznamu dat, která jsou naplněna vlastností ItemSource
. Strategie RecycleElement
ukládání do mezipaměti se pokouší minimalizovat ListView
nároky na paměť a rychlost provádění recyklací buněk seznamu. Další informace naleznete v tématu Strategie ukládání do mezipaměti.
Každý řádek v seznamu obsahuje tři položky dat – název, kategorii a název souboru obrázku. Rozložení každého řádku v seznamu je definováno odkazem DataTemplate
na ListView.ItemTemplate
vlastnost bindable. Definuje DataTemplate
, že každý řádek dat v seznamu bude NativeCell
zobrazen jeho Name
, Category
a ImageFilename
vlastnosti prostřednictvím datové vazby. Další informace o ovládacím ListView
prvku naleznete v tématu ListView.
Do každého projektu aplikace je teď možné přidat vlastní renderer, který přizpůsobí rozložení specifické pro danou platformu pro každou buňku.
Vytvoření vlastního rendereru na jednotlivých platformách
Proces vytvoření vlastní třídy rendereru je následující:
- Vytvořte podtřídu
ViewCellRenderer
třídy, která vykreslí vlastní buňku. - Přepište metodu specifickou pro platformu, která vykreslí vlastní buňku a logiku zápisu, aby ji přizpůsobila.
ExportRenderer
Přidejte atribut do vlastní třídy rendereru, aby bylo možné určit, že se použije k vykreslení Xamarin.Forms vlastní buňky. Tento atribut se používá k registraci vlastního rendereru v Xamarin.Forms.
Poznámka:
Pro většinu Xamarin.Forms prvků je volitelné poskytnout vlastní renderer v každém projektu platformy. Pokud není zaregistrovaný vlastní renderer, použije se výchozí renderer základní třídy ovládacího prvku. Vlastní renderery jsou však vyžadovány v každém projektu platformy při vykreslování elementu ViewCell .
Následující diagram znázorňuje zodpovědnosti jednotlivých projektů v ukázkové aplikaci spolu s relacemi mezi nimi:
Vlastní NativeCell
buňka je vykreslena třídami rendereru specifické pro platformu, které jsou odvozeny od třídy pro každou platformu ViewCellRenderer
. Výsledkem je vykreslení každé NativeCell
vlastní buňky s rozložením specifické pro platformu, jak je znázorněno na následujících snímcích obrazovky:
Třída ViewCellRenderer
zveřejňuje metody specifické pro platformu pro vykreslení vlastní buňky. Jedná se o metodu GetCell
na platformě iOS, metodu GetCellCore
na platformě Android a metodu GetTemplate
v UPW.
Každá vlastní třída rendereru je zdobena ExportRenderer
atributem, který registruje renderer s Xamarin.Forms. Atribut má dva parametry – název Xamarin.Forms typu vykreslené buňky a název typu vlastního rendereru. Předpona assembly
atributu určuje, že atribut se vztahuje na celé sestavení.
Následující části se týkají implementace jednotlivých vlastních tříd rendereru specifických pro platformu.
Vytvoření vlastního rendereru v iOSu
Následující příklad kódu ukazuje vlastní renderer pro platformu iOS:
[assembly: ExportRenderer(typeof(NativeCell), typeof(NativeiOSCellRenderer))]
namespace CustomRenderer.iOS
{
public class NativeiOSCellRenderer : ViewCellRenderer
{
NativeiOSCell cell;
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var nativeCell = (NativeCell)item;
cell = reusableCell as NativeiOSCell;
if (cell == null)
cell = new NativeiOSCell(item.GetType().FullName, nativeCell);
else
cell.NativeCell.PropertyChanged -= OnNativeCellPropertyChanged;
nativeCell.PropertyChanged += OnNativeCellPropertyChanged;
cell.UpdateCell(nativeCell);
return cell;
}
...
}
}
Metoda GetCell
je volána k sestavení každé buňky, která se má zobrazit. Každá buňka je NativeiOSCell
instance, která definuje rozložení buňky a jejích dat. Operace GetCell
metody závisí na ListView
strategii ukládání do mezipaměti:
ListView
Pokud jeRetainElement
strategie ukládání do mezipaměti , metoda bude vyvolána pro každou buňkuGetCell
. VytvoříNativeiOSCell
se instance pro každouNativeCell
instanci, která se na obrazovce zpočátku zobrazí. Při procházeníListView
NativeiOSCell
uživatelem se instance znovu použijí. Další informace o opětovném použití buněk iOS naleznete v tématu Opakované použití buňky.Poznámka:
Tento vlastní kód rendereru provede opakované použití některých buněk i v případě, že
ListView
je nastavena pro zachování buněk.Data zobrazená každou
NativeiOSCell
instancí, ať už nově vytvořená nebo znovu použitá, se aktualizují o data z každéNativeCell
instance metodouUpdateCell
.Poznámka:
Metoda
OnNativeCellPropertyChanged
se nikdy nevyvolá, kdyžListView
je strategie ukládání do mezipaměti nastavena pro zachování buněk.ListView
Při strategiiRecycleElement
GetCell
ukládání do mezipaměti se metoda vyvolá pro každou buňku, která se na obrazovce zpočátku zobrazí. VytvoříNativeiOSCell
se instance pro každouNativeCell
instanci, která se na obrazovce zpočátku zobrazí. Data zobrazená každouNativeiOSCell
instancí se aktualizují o data zNativeCell
instance metodouUpdateCell
. Metoda se však nevyvolá,GetCell
protože uživatel prochází rozhranímListView
.NativeiOSCell
Místo toho se instance znovu použijí.PropertyChanged
události budou v instanci vyvolányNativeCell
při změně dat a obslužná rutinaOnNativeCellPropertyChanged
události aktualizuje data v každé znovu použitéNativeiOSCell
instanci.
Následující příklad kódu ukazuje metodu OnNativeCellPropertyChanged
, která se vyvolá při PropertyChanged
vyvolání události:
namespace CustomRenderer.iOS
{
public class NativeiOSCellRenderer : ViewCellRenderer
{
...
void OnNativeCellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var nativeCell = (NativeCell)sender;
if (e.PropertyName == NativeCell.NameProperty.PropertyName)
{
cell.HeadingLabel.Text = nativeCell.Name;
}
else if (e.PropertyName == NativeCell.CategoryProperty.PropertyName)
{
cell.SubheadingLabel.Text = nativeCell.Category;
}
else if (e.PropertyName == NativeCell.ImageFilenameProperty.PropertyName)
{
cell.CellImageView.Image = cell.GetImage(nativeCell.ImageFilename);
}
}
}
}
Tato metoda aktualizuje data zobrazená opětovnými instancemi NativeiOSCell
. Kontrola změněné vlastnosti se provede, protože metodu lze volat vícekrát.
Třída NativeiOSCell
definuje rozložení pro každou buňku a je znázorněna v následujícím příkladu kódu:
internal class NativeiOSCell : UITableViewCell, INativeElementView
{
public UILabel HeadingLabel { get; set; }
public UILabel SubheadingLabel { get; set; }
public UIImageView CellImageView { get; set; }
public NativeCell NativeCell { get; private set; }
public Element Element => NativeCell;
public NativeiOSCell(string cellId, NativeCell cell) : base(UITableViewCellStyle.Default, cellId)
{
NativeCell = cell;
SelectionStyle = UITableViewCellSelectionStyle.Gray;
ContentView.BackgroundColor = UIColor.FromRGB(255, 255, 224);
CellImageView = new UIImageView();
HeadingLabel = new UILabel()
{
Font = UIFont.FromName("Cochin-BoldItalic", 22f),
TextColor = UIColor.FromRGB(127, 51, 0),
BackgroundColor = UIColor.Clear
};
SubheadingLabel = new UILabel()
{
Font = UIFont.FromName("AmericanTypewriter", 12f),
TextColor = UIColor.FromRGB(38, 127, 0),
TextAlignment = UITextAlignment.Center,
BackgroundColor = UIColor.Clear
};
ContentView.Add(HeadingLabel);
ContentView.Add(SubheadingLabel);
ContentView.Add(CellImageView);
}
public void UpdateCell(NativeCell cell)
{
HeadingLabel.Text = cell.Name;
SubheadingLabel.Text = cell.Category;
CellImageView.Image = GetImage(cell.ImageFilename);
}
public UIImage GetImage(string filename)
{
return (!string.IsNullOrWhiteSpace(filename)) ? UIImage.FromFile("Images/" + filename + ".jpg") : null;
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
HeadingLabel.Frame = new CGRect(5, 4, ContentView.Bounds.Width - 63, 25);
SubheadingLabel.Frame = new CGRect(100, 18, 100, 20);
CellImageView.Frame = new CGRect(ContentView.Bounds.Width - 63, 5, 33, 33);
}
}
Tato třída definuje ovládací prvky použité k vykreslení obsahu buňky a jejich rozložení. Třída implementuje INativeElementView
rozhraní, které je vyžadováno ListView
při použití RecycleElement
strategie ukládání do mezipaměti. Toto rozhraní určuje, že třída musí implementovat Element
vlastnost, která by měla vrátit vlastní data buněk pro recyklované buňky.
Konstruktor NativeiOSCell
inicializuje vzhled HeadingLabel
, SubheadingLabel
a CellImageView
vlastnosti. Tyto vlastnosti se používají k zobrazení dat uložených v NativeCell
instanci s metodou UpdateCell
, která je volána k nastavení hodnoty každé vlastnosti. Kromě toho, když ListView
používá RecycleElement
strategie ukládání do mezipaměti, data zobrazená HeadingLabel
pomocí , SubheadingLabel
a CellImageView
vlastnosti mohou být aktualizovány metodou OnNativeCellPropertyChanged
ve vlastním rendereru.
Rozložení buňky se provádí přepsáním LayoutSubviews
, které nastavuje souřadnice HeadingLabel
, SubheadingLabel
a CellImageView
v buňce.
Vytvoření vlastního rendereru v Androidu
Následující příklad kódu ukazuje vlastní renderer pro platformu Android:
[assembly: ExportRenderer(typeof(NativeCell), typeof(NativeAndroidCellRenderer))]
namespace CustomRenderer.Droid
{
public class NativeAndroidCellRenderer : ViewCellRenderer
{
NativeAndroidCell cell;
protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView, ViewGroup parent, Context context)
{
var nativeCell = (NativeCell)item;
Console.WriteLine("\t\t" + nativeCell.Name);
cell = convertView as NativeAndroidCell;
if (cell == null)
{
cell = new NativeAndroidCell(context, nativeCell);
}
else
{
cell.NativeCell.PropertyChanged -= OnNativeCellPropertyChanged;
}
nativeCell.PropertyChanged += OnNativeCellPropertyChanged;
cell.UpdateCell(nativeCell);
return cell;
}
...
}
}
Metoda GetCellCore
je volána k sestavení každé buňky, která se má zobrazit. Každá buňka je NativeAndroidCell
instance, která definuje rozložení buňky a jejích dat. Operace GetCellCore
metody závisí na ListView
strategii ukládání do mezipaměti:
ListView
Pokud jeRetainElement
strategie ukládání do mezipaměti , metoda bude vyvolána pro každou buňkuGetCellCore
. VytvoříNativeAndroidCell
se pro každouNativeCell
instanci, která se na obrazovce zpočátku zobrazí. Při procházeníListView
NativeAndroidCell
uživatelem se instance znovu použijí. Další informace o opětovném použití buňky Androidu najdete v tématu Opětovné použití zobrazení řádků.Poznámka:
Všimněte si, že tento vlastní kód rendereru provede opakované použití některých buněk i v případě, že
ListView
je nastavena pro zachování buněk.Data zobrazená každou
NativeAndroidCell
instancí, ať už nově vytvořená nebo znovu použitá, se aktualizují o data z každéNativeCell
instance metodouUpdateCell
.Poznámka:
Všimněte si, že zatímco
OnNativeCellPropertyChanged
metoda bude vyvolána, kdyžListView
je nastavena na zachování buněk, nebude aktualizovatNativeAndroidCell
hodnoty vlastnosti.ListView
Při strategiiRecycleElement
GetCellCore
ukládání do mezipaměti se metoda vyvolá pro každou buňku, která se na obrazovce zpočátku zobrazí. VytvoříNativeAndroidCell
se instance pro každouNativeCell
instanci, která se na obrazovce zpočátku zobrazí. Data zobrazená každouNativeAndroidCell
instancí se aktualizují o data zNativeCell
instance metodouUpdateCell
. Metoda se však nevyvolá,GetCellCore
protože uživatel prochází rozhranímListView
.NativeAndroidCell
Místo toho se instance znovu použijí.PropertyChanged
události budou v instanci vyvolányNativeCell
při změně dat a obslužná rutinaOnNativeCellPropertyChanged
události aktualizuje data v každé znovu použitéNativeAndroidCell
instanci.
Následující příklad kódu ukazuje metodu OnNativeCellPropertyChanged
, která se vyvolá při PropertyChanged
vyvolání události:
namespace CustomRenderer.Droid
{
public class NativeAndroidCellRenderer : ViewCellRenderer
{
...
void OnNativeCellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var nativeCell = (NativeCell)sender;
if (e.PropertyName == NativeCell.NameProperty.PropertyName)
{
cell.HeadingTextView.Text = nativeCell.Name;
}
else if (e.PropertyName == NativeCell.CategoryProperty.PropertyName)
{
cell.SubheadingTextView.Text = nativeCell.Category;
}
else if (e.PropertyName == NativeCell.ImageFilenameProperty.PropertyName)
{
cell.SetImage(nativeCell.ImageFilename);
}
}
}
}
Tato metoda aktualizuje data zobrazená opětovnými instancemi NativeAndroidCell
. Kontrola změněné vlastnosti se provede, protože metodu lze volat vícekrát.
Třída NativeAndroidCell
definuje rozložení pro každou buňku a je znázorněna v následujícím příkladu kódu:
internal class NativeAndroidCell : LinearLayout, INativeElementView
{
public TextView HeadingTextView { get; set; }
public TextView SubheadingTextView { get; set; }
public ImageView ImageView { get; set; }
public NativeCell NativeCell { get; private set; }
public Element Element => NativeCell;
public NativeAndroidCell(Context context, NativeCell cell) : base(context)
{
NativeCell = cell;
var view = (context as Activity).LayoutInflater.Inflate(Resource.Layout.NativeAndroidCell, null);
HeadingTextView = view.FindViewById<TextView>(Resource.Id.HeadingText);
SubheadingTextView = view.FindViewById<TextView>(Resource.Id.SubheadingText);
ImageView = view.FindViewById<ImageView>(Resource.Id.Image);
AddView(view);
}
public void UpdateCell(NativeCell cell)
{
HeadingTextView.Text = cell.Name;
SubheadingTextView.Text = cell.Category;
// Dispose of the old image
if (ImageView.Drawable != null)
{
using (var image = ImageView.Drawable as BitmapDrawable)
{
if (image != null)
{
if (image.Bitmap != null)
{
image.Bitmap.Dispose();
}
}
}
}
SetImage(cell.ImageFilename);
}
public void SetImage(string filename)
{
if (!string.IsNullOrWhiteSpace(filename))
{
// Display new image
Context.Resources.GetBitmapAsync(filename).ContinueWith((t) =>
{
var bitmap = t.Result;
if (bitmap != null)
{
ImageView.SetImageBitmap(bitmap);
bitmap.Dispose();
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
else
{
// Clear the image
ImageView.SetImageBitmap(null);
}
}
}
Tato třída definuje ovládací prvky použité k vykreslení obsahu buňky a jejich rozložení. Třída implementuje INativeElementView
rozhraní, které je vyžadováno ListView
při použití RecycleElement
strategie ukládání do mezipaměti. Toto rozhraní určuje, že třída musí implementovat Element
vlastnost, která by měla vrátit vlastní data buněk pro recyklované buňky.
Konstruktor NativeAndroidCell
nafoukne NativeAndroidCell
rozložení a inicializuje HeadingTextView
, SubheadingTextView
a ImageView
vlastnosti ovládacích prvků v nafukované rozložení. Tyto vlastnosti se používají k zobrazení dat uložených v NativeCell
instanci s metodou UpdateCell
, která je volána k nastavení hodnoty každé vlastnosti. Kromě toho, když ListView
používá RecycleElement
strategie ukládání do mezipaměti, data zobrazená HeadingTextView
pomocí , SubheadingTextView
a ImageView
vlastnosti mohou být aktualizovány metodou OnNativeCellPropertyChanged
ve vlastním rendereru.
Následující příklad kódu ukazuje definici rozložení pro NativeAndroidCell.axml
soubor rozložení:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:background="@drawable/CustomSelector">
<LinearLayout
android:id="@+id/Text"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip">
<TextView
android:id="@+id/HeadingText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF7F3300"
android:textSize="20dip"
android:textStyle="italic" />
<TextView
android:id="@+id/SubheadingText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dip"
android:textColor="#FF267F00"
android:paddingLeft="100dip" />
</LinearLayout>
<ImageView
android:id="@+id/Image"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="5dp"
android:src="@drawable/icon"
android:layout_alignParentRight="true" />
</RelativeLayout>
Toto rozložení určuje, že se k zobrazení obsahu buňky používají dva TextView
ovládací prvky a ImageView
ovládací prvek. Tyto dva TextView
ovládací prvky jsou svisle orientované v LinearLayout
rámci ovládacího prvku, přičemž všechny ovládací prvky obsažené v objektu RelativeLayout
.
Vytvoření vlastního rendereru v UPW
Následující příklad kódu ukazuje vlastní renderer pro UPW:
[assembly: ExportRenderer(typeof(NativeCell), typeof(NativeUWPCellRenderer))]
namespace CustomRenderer.UWP
{
public class NativeUWPCellRenderer : ViewCellRenderer
{
public override Windows.UI.Xaml.DataTemplate GetTemplate(Cell cell)
{
return App.Current.Resources["ListViewItemTemplate"] as Windows.UI.Xaml.DataTemplate;
}
}
}
Volá GetTemplate
se metoda pro vrácení buňky, která se má vykreslit pro každý řádek dat v seznamu. Vytvoří DataTemplate
pro každou NativeCell
instanci, která se zobrazí na obrazovce, s DataTemplate
definováním vzhledu a obsahu buňky.
Soubor DataTemplate
je uložený ve slovníku prostředků na úrovni aplikace a je zobrazený v následujícím příkladu kódu:
<DataTemplate x:Key="ListViewItemTemplate">
<Grid Background="LightYellow">
<Grid.Resources>
<local:ConcatImageExtensionConverter x:Name="ConcatImageExtensionConverter" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.40*" />
<ColumnDefinition Width="0.40*"/>
<ColumnDefinition Width="0.20*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.ColumnSpan="2" Foreground="#7F3300" FontStyle="Italic" FontSize="22" VerticalAlignment="Top" Text="{Binding Name}" />
<TextBlock Grid.RowSpan="2" Grid.Column="1" Foreground="#267F00" FontWeight="Bold" FontSize="12" VerticalAlignment="Bottom" Text="{Binding Category}" />
<Image Grid.RowSpan="2" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Center" Source="{Binding ImageFilename, Converter={StaticResource ConcatImageExtensionConverter}}" Width="50" Height="50" />
<Line Grid.Row="1" Grid.ColumnSpan="3" X1="0" X2="1" Margin="30,20,0,0" StrokeThickness="1" Stroke="LightGray" Stretch="Fill" VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
Určuje DataTemplate
ovládací prvky použité k zobrazení obsahu buňky a jejich rozložení a vzhledu. Dva TextBlock
ovládací prvky a Image
ovládací prvek slouží k zobrazení obsahu buňky prostřednictvím datové vazby. Kromě toho se instance souboru ConcatImageExtensionConverter
používá ke zřetězení přípony .jpg
souboru pro každý název souboru obrázku. Tím se zajistí, že Image
ovládací prvek může načíst a vykreslit obrázek, když je nastavena Source
jeho vlastnost.
Shrnutí
Tento článek ukazuje, jak vytvořit vlastní renderer pro ovládací ViewCell
prvek hostovaný v ovládacím Xamarin.FormsListView
prvku. Tím se zastaví Xamarin.Forms opakované vyvolání výpočtů rozložení během ListView
posouvání.