Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Esnek düzen sistemi, özel görünümler ve sanallaştırma kullanarak özel koleksiyon deneyimleri oluşturmak için ItemsRepeater kullanın.
ListView'un aksine, ItemsRepeater kapsamlı bir son kullanıcı deneyimi sağlamaz; varsayılan kullanıcı arabirimi yoktur ve odak, seçim veya kullanıcı etkileşimiyle ilgili bir ilke sağlamaz. Bunun yerine, kendi benzersiz koleksiyon tabanlı deneyimlerinizi ve özel denetimlerinizi oluşturmak için kullanabileceğiniz bir yapı taşıdır. Yerleşik bir ilkesi olmasa da, ihtiyacınız olan deneyimi oluşturmak için ilke eklemenize olanak tanır. Örneğin, kullanılacak düzeni, klavye ilkesini, seçim ilkesini vb. tanımlayabilirsiniz.
ItemsRepeater'ı ListView gibi tam bir denetim yerine kavramsal olarak veri odaklı bir panel olarak düşünebilirsiniz. Görüntülenecek veri öğeleri koleksiyonunu, her veri öğesi için kullanıcı arabirimi öğesi oluşturan bir öğe şablonunu ve öğelerin nasıl boyutlandırıldığını ve konumlandırıldığını belirleyen bir düzen belirtirsiniz. Ardından ItemsRepeater, veri kaynağına dayalı alt öğeler oluşturur ve bunları, öğe şablonu ve düzenince belirtilen şekilde görüntüler. Görüntülenen öğelerin homojen olması gerekmez çünkü ItemsRepeater, veri şablonu seçicisinde belirttiğiniz ölçütlere göre veri öğelerini temsil eden içerik yükleyebilir.
Doğru kontrol bu mu?
Veri koleksiyonları için özel ekranlar oluşturmak için ItemsRepeater kullanın. Temel bir öğe kümesi sunmak için kullanılabilse de, bunu genellikle özel denetimin şablonunda görüntüleme öğesi olarak kullanabilirsiniz.
Liste veya tablodaki verileri minimum özelleştirmeyle görüntülemek için kullanıma hazır bir denetime ihtiyacınız varsa, ListView veya GridViewkullanmayı göz önünde bulundurun.
ItemsRepeater'ın yerleşik Bir Items koleksiyonu yok. Ayrı bir veri kaynağına bağlamak yerine doğrudan bir Items koleksiyonu sağlamanız gerekiyorsa, büyük olasılıkla daha yüksek ilkeli bir deneyime ihtiyacınız vardır ve ListView veya GridView kullanmanız gerekir.
ItemsControl ve ItemsRepeater'ın her ikisi de özelleştirilebilir koleksiyon deneyimlerini etkinleştirir, ancak ItemsRepeater kullanıcı arabirimi düzenlerini sanallaştırmayı desteklerken ItemsControl bunu desteklemez. Yalnızca verilerden birkaç öğe sunmak veya özel bir koleksiyon denetimi oluşturmak için ItemsControl yerine ItemsRepeater kullanmanızı öneririz.
ItemsRepeater ile kaydırma
ItemsRepeaterControltürememektedir, bu nedenle bir kontrol şablonu yoktur. Bu nedenle, ListView veya diğer koleksiyon denetimleri gibi yerleşik kaydırma içermez.
ItemsRepeaterkullandığınızda, ScrollViewer denetimi kullanarak kaydırma işlevi sağlamanız gerekir.
Uyarı
Uygulamanız Windows 10, sürüm 1809'dan önce
<muxc:ItemsRepeaterScrollHost>
<ScrollViewer>
<muxc:ItemsRepeater ... />
</ScrollViewer>
</muxc:ItemsRepeaterScrollHost>
Uygulamanız yalnızca Windows 10, sürüm 1809 ve sonraki sürümleriyle çalışacaksa ItemsRepeaterScrollHost'u kullanmanız gerekmez.
Windows 10, sürüm 1809'dan önce
ItemsRepeater oluşturma
- Önemli API'ler: ItemsRepeater sınıfı, ScrollViewer sınıfı
WinUI 3 Galeri uygulaması çoğu WinUI 3 denetimi, özelliği ve işlevselliğine ilişkin etkileşimli örnekler içerir. Uygulamayı Microsoft Store'dan alın veya GitHub'dan kaynak kodunu alın
ItemsRepeater kullanmak için ItemsSource özelliğini ayarlayarak görüntülenecek verileri vermeniz gerekir. Ardından ItemTemplate özelliğini ayarlayarak öğelerin nasıl görüntüleneceğini anlatın.
Öğe Kaynağı
Görünümü doldurmak için ItemsSource özelliğini bir veri öğeleri koleksiyonu olarak ayarlayın. Burada, ItemsSource kodda doğrudan bir koleksiyonun örneğine ayarlanır.
ObservableCollection<string> Items = new ObservableCollection<string>();
ItemsRepeater itemsRepeater1 = new ItemsRepeater();
itemsRepeater1.ItemsSource = Items;
ItemsSource özelliğini XAML'deki bir koleksiyona da bağlayabilirsiniz. Veri bağlama hakkında daha fazla bilgi için bkz. Veri bağlamaya genel bakış.
<ItemsRepeater ItemsSource="{x:Bind Items}"/>
Öğe Şablonu
Bir veri öğesinin nasıl görselleştirileceğini belirtmek için ItemTemplate özelliğini tanımladığınız bir DataTemplate veya DataTemplateSelector olarak ayarlayın. Veri şablonu, verilerin nasıl görselleştirildiği tanımlar. Varsayılan olarak, öğe görünümde TextBlock ile görüntülenir ve veri nesnesinin dize gösterimini kullanır.
Ancak, genellikle tek bir öğeyi görüntülemek için kullanacağınız bir veya daha fazla denetimin düzenini ve görünümünü tanımlayan bir şablon kullanarak verilerinizin daha zengin bir sunumunu göstermek istersiniz. Şablonda kullandığınız denetimler veri nesnesinin özelliklerine bağlanabilir veya statik içerik satır içinde tanımlanmış olabilir.
Veri Şablonu
Bu örnekte veri nesnesi basit bir dizedir. DataTemplate, metnin solunda bir resim barındırır ve dizeyi camgöbeği renginde görüntülemek için TextBlock'yi stillendirir.
Uyarı
bir
<DataTemplate x:DataType="x:String">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="47"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="Assets/placeholder.png" Width="32" Height="32"
HorizontalAlignment="Left"/>
<TextBlock Text="{x:Bind}" Foreground="Teal"
FontSize="15" Grid.Column="1"/>
</Grid>
</DataTemplate>
Bu DataTemplate ile görüntülendiğinde öğelerin nasıl görüneceği aşağıda anlatılır.
Bir öğe için DataTemplate'da kullanılan öğe sayısı, görünümünüzün çok sayıda öğe görüntülemesi durumunda performansı önemli ölçüde etkileyebilir. Listenizdeki öğelerin görünümünü tanımlamak için DataTemplatekullanma hakkında daha fazla bilgi ve örnek için bkz . Öğe kapsayıcıları ve şablonları.
İpucu
Kolaylık sağlamak için, şablonu statik bir kaynak olarak referans vermek yerine satır içinden bildirmek istediğinizde, ItemsRepeateröğesinin doğrudan alt öğesi olarak DataTemplate veya DataTemplateSelector belirtebilirsiniz. ItemTemplate özelliğinin değeri olarak atanır. Örneğin, bu geçerli:
<ItemsRepeater ItemsSource="{x:Bind Items}">
<DataTemplate>
<!-- ... -->
</DataTemplate>
</ItemsRepeater>
İpucu
ListView ve diğer koleksiyon denetimlerinden farklı olarak ItemsRepeater, DataTemplate içindeki öğeleri kenar boşlukları, doldurma, seçim görselleri veya görsel durumu üzerinde işaretçi gibi varsayılan ilkeyi içeren ek bir öğe kapsayıcısıyla sarmalamaz. Bunun yerine , ItemsRepeater yalnızca DataTemplate içinde tanımlananları sunar. Öğelerinizin liste görünümü öğesiyle aynı görünüme sahip olmasını istiyorsanız, veri şablonunuzdaki ListViewItem gibi bir kapsayıcıyı açıkça ekleyebilirsiniz. ItemsRepeaterListViewItem görsellerini gösterir, ancak seçim veya çoklu seçim onay kutusunu gösterme gibi diğer işlevleri otomatik olarak kullanmaz.
Benzer şekilde, veri koleksiyonunuz Button ()List<Button> gibi gerçek denetimlerden oluşan bir koleksiyonsa, denetimi görüntülemek için DataTemplate'ınıza bir ContentPresenter ekleyebilirsiniz.
Veri Şablonu Seçici
Görünümünüzde görüntülediğiniz öğelerin aynı türde olması gerekmez. Belirttiğiniz ölçütlere göre farklı DataTemplateseçmek için DataTemplateSelectorItemTemplate özelliğini sağlayabilirsiniz.
Bu örnekte, büyük ve küçük bir öğeyi temsil etmek için iki farklı DataTemplate arasında karar veren bir DataTemplateSelectortanımlandığı varsayılır.
<ItemsRepeater ...>
<ItemsRepeater.ItemTemplate>
<local:VariableSizeTemplateSelector Large="{StaticResource LargeItemTemplate}"
Small="{StaticResource SmallItemTemplate}"/>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
ItemsRepeater ile kullanılacak bir DataTemplateSelector tanımlarken yalnızca SelectTemplateCore(Nesne) yöntemi için bir geçersiz kılma uygulamanız gerekir. Daha fazla bilgi ve örnek için bkz. DataTemplateSelector.
Uyarı
Daha gelişmiş senaryolarda öğelerin nasıl oluşturulduğunu yönetmek için, DataTemplate'e bir alternatif olarak, ItemTemplateolarak kullanmak üzere kendi IElementFactory'i uygulamaktır. İstendiğinde içerik oluşturmaktan sorumlu olacaktır.
Veri kaynağını yapılandırma
Öğelerin içeriğini oluşturmak için kullanılacak koleksiyonu belirtmek için ItemsSource özelliğini kullanın. ItemsSource'yi IEnumerablearayüzünü uygulayan herhangi bir türe ayarlayabilirsiniz. Veri kaynağınız tarafından uygulanan ek koleksiyon arabirimleri, ItemsRepeater'ın verilerinizle etkileşime geçmek için kullanabileceği işlevleri belirler.
Bu listede kullanılabilir arabirimler ve bunların ne zaman kullanılması gerekir gösterilir.
IEnumerable(.NET) / IIterable
Küçük, statik veri kümeleri için kullanılabilir.
Veri kaynağının en azından IEnumerable / IIterable arabirimini uygulaması gerekir. Desteklenen tek şey buysa, denetim her şeyi bir kez yineler ve bir dizin değeri aracılığıyla öğelere erişmek için kullanabileceği bir kopya oluşturur.
IReadonlyList(.NET) / IVectorView
Statik, salt okunur veri kümeleri için kullanılabilir.
Denetimin öğelere dizine göre erişmesini sağlar ve yedekli iç kopyayı önler.
-
Statik veri kümeleri için kullanılabilir.
Denetimin öğelere dizine göre erişmesini sağlar ve yedekli iç kopyayı önler.
Uyarı: INotifyCollectionChanged uygulanmadan listede/vektörde yapılan değişiklikler kullanıcı arabirimine yansıtılmayacaktır.
INotifyCollectionChanged(.NET)
Değişiklik bildirimini desteklemek için önerilir.
Denetimin veri kaynağındaki değişiklikleri gözlemleyip bunlara tepki vermesini ve bu değişiklikleri kullanıcı arabiriminde yansıtmasını sağlar.
-
Değişiklik bildirimini destekler
INotifyCollectionChanged arabiriminde olduğu gibi, bu da denetimin veri kaynağındaki değişiklikleri gözlemlesine ve bunlara tepki vermesine olanak tanır.
Uyarı: Windows.Foundation.IObservableVector<T> bir 'Taşı' eylemini desteklemez. Bu, bir öğenin kullanıcı arabiriminin görsel durumunu kaybetmesine neden olabilir. Örneğin, şu anda seçili olan ve/veya taşıma işleminin 'Kaldır' ve ardından 'Ekle' ile gerçekleştirildiği bir öğe odağı kaybeder ve artık seçilemez.
Platform.Collections.Vector<T> , IObservableVector<T> kullanır ve bu sınırlamaya sahiptir. 'Taşı' eylemi için destek gerekiyorsa INotifyCollectionChanged arabirimini kullanın. .NET ObservableCollection<T> sınıfı INotifyCollectionChanged kullanır.
-
Her öğeyle benzersiz bir tanımlayıcı ilişkilendirilebildiği durumlarda. 'Sıfırla' işlemi koleksiyon değişikliği eylemi olarak kullanılırken önerilir.
INotifyCollectionChanged veya IObservableVector olayının parçası olarak bir 'Sıfırlama' eylemi aldıktan sonra, denetimin mevcut UI'yi çok verimli bir şekilde geri yüklemesini sağlar. Sıfırlama aldıktan sonra denetim, geçerli verileri önceden oluşturduğu öğelerle ilişkilendirmek için sağlanan benzersiz kimliği kullanır. Dizin eşleme anahtarı olmadan, denetimin veriler için kullanıcı arabirimi oluştururken sıfırdan başlaması gerektiğini varsayması gerekir.
Yukarıda listelenen arabirimler, IKeyIndexMapping dışında, ItemsRepeater'da ListView ve GridView'da olduğu gibi aynı davranışı sağlar.
Bir ItemsSource'taki aşağıdaki arabirimler ListView ve GridView denetimlerinde özel işlevleri etkinleştirir, ancak şu anda ItemsRepeater üzerinde hiçbir etkisi yoktur:
İpucu
Geri bildiriminizi istiyoruz! WinUI GitHub projesiyle ilgili düşüncelerinizi bize bildirin. Mevcut tekliflerle ilgili düşüncelerinizi eklemeyi düşünün: #374: ItemsRepeater için artımlı yükleme desteği ekleme.
Kullanıcı yukarı veya aşağı kaydırılırken verilerinizi artımlı olarak yüklemek için alternatif bir yaklaşım, ScrollViewer görünüm penceresi konumunu gözlemlemek ve görünüm penceresi boyuta yaklaştıkça daha fazla veri yüklemektir.
<ScrollViewer ViewChanged="ScrollViewer_ViewChanged">
<ItemsRepeater ItemsSource="{x:Bind MyItemsSource}" .../>
</ScrollViewer>
private async void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (!e.IsIntermediate)
{
var scroller = (ScrollViewer)sender;
var distanceToEnd = scroller.ExtentHeight - (scroller.VerticalOffset + scroller.ViewportHeight);
// trigger if within 2 viewports of the end
if (distanceToEnd <= 2.0 * scroller.ViewportHeight
&& MyItemsSource.HasMore && !itemsSource.Busy)
{
// show an indeterminate progress UI
myLoadingIndicator.Visibility = Visibility.Visible;
await MyItemsSource.LoadMoreItemsAsync(/*DataFetchSize*/);
loadingIndicator.Visibility = Visibility.Collapsed;
}
}
}
Öğelerin düzenini değiştirme
ItemsRepeater tarafından gösterilen öğeler, alt öğelerinin boyutunu ve konumlandırmasını yöneten bir Düzeni nesnesi tarafından düzenlenir. ItemsRepeater ile kullanıldığında, Düzen nesnesi kullanıcı arabirimi sanallaştırmasını etkinleştirir. Sağlanan düzenler StackLayout ve UniformGridLayout. Varsayılan olarak, ItemsRepeater dikey yönlendirmeli bir StackLayout kullanır.
StackLayout
StackLayout , öğeleri yatay veya dikey olarak yönlendirebileceğiniz tek bir çizgi halinde düzenler.
Öğeler arasındaki boşluk miktarını ayarlamak için Aralık özelliğini ayarlayabilirsiniz. Düzenin Yönlendirmeyönünde aralık olarak uygulanır.
Bu örnekte ItemsRepeater.Layout özelliğini yatay yönlendirme ve 8 piksel aralığı olan bir StackLayout olarak ayarlama gösterilmektedir.
<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<muxc:ItemsRepeater ItemsSource="{x:Bind Items}" ItemTemplate="{StaticResource MyTemplate}">
<muxc:ItemsRepeater.Layout>
<muxc:StackLayout Orientation="Horizontal" Spacing="8"/>
</muxc:ItemsRepeater.Layout>
</muxc:ItemsRepeater>
UniformGridLayout
UniformGridLayout, öğeleri bir sarma düzeninde sıralı olarak konumlandırır. Öğeler, Yönlendirme Yatay olduğunda soldan sağa doğru düzenlenir ve YönlendirmeDikey olduğunda yukarıdan aşağıya doğru düzenlenir. Her öğe eşit olarak boyutlandırılır.
Yatay düzenin her satırındaki öğe sayısı, en düşük öğe genişliğinden etkilenir. Dikey düzenin her sütunundaki öğe sayısı, en düşük öğe yüksekliğinden etkilenir.
- MinItemHeight
ayarlayarak ve MinItemWidth özelliklerini açıkça en düşük boyutu sağlayabilirsiniz. - Minimum boyut belirtmezseniz, ilk öğenin ölçülen boyutu, öğe başına minimum boyut olarak kabul edilir.
Ayrıca, MinColumnSpacing
Bir satır veya sütundaki öğelerin sayısı, öğenin en küçük boyutuna ve aralığına göre belirlendikten sonra, satır veya sütundaki son öğeden sonra kullanılmayan boşluk olabilir (önceki resimde gösterildiği gibi). Herhangi bir ek alanın yoksayılacağını, her öğenin boyutunu artırmak için mi yoksa öğeler arasında ek alan oluşturmak için mi kullanılacağını belirtebilirsiniz. Bu, ItemsStretch ve ItemsJustification özellikleri tarafından denetlenmektedir .
Öğe boyutunun kullanılmayan alanı dolduracak şekilde nasıl artırılacağını belirtmek için ItemsStretch özelliğini ayarlayabilirsiniz.
Bu listede kullanılabilir değerler gösterilir. Tanımlar, varsayılan Yönlendirme'nin Yatay olduğunu varsayar.
- Yok: Satırın sonunda fazladan alan kullanılmamış olarak bırakılır. Bu varsayılan seçenektir.
- Dolgu: Mevcut alanı (dikey durumda yükseklik) kullanmak için öğelerin genişliği artırılır.
- Tekdüzen: Öğelere kullanılabilir alanı kullanmak için fazladan genişlik verilir ve en boy oranını korumak için fazladan yükseklik verilir (dikeyse yükseklik ve genişlik değiştirilir).
Bu görüntüde ItemsStretch değerlerinin yatay düzendeki etkisi gösterilir.
ItemsStretchHiçbiriolduğunda, öğeleri hizalamak için ek alanın nasıl kullanılacağını belirtmek üzere ItemsJustification özelliğini ayarlayabilirsiniz.
Bu listede kullanılabilir değerler gösterilir. Tanımlar, varsayılan Yönlendirme'nin Yatay olduğunu varsayar.
- Başlangıç: Öğeler satırın başlangıcıyla hizalanır. Satırın sonunda kalan fazladan alan kullanılmadan bırakılır. Bu varsayılan seçenektir.
- Ortala: Öğeler satırın ortasına hizalanır. Ek alan satırın başında ve sonunda eşit olarak bölünür.
- Bitiş: Öğeler satırın sonuna hizalanır. Satırın başında fazladan boşluk kullanılmamış bırakılır.
- Ara Çubuğu: Öğeler eşit olarak dağıtılır. Her öğeden önce ve sonra eşit miktarda alan eklenir.
- SpaceBetween: Öğeler eşit olarak dağıtılır. Her öğe arasına eşit miktarda alan eklenir. Satırın başlangıcına ve sonuna boşluk eklenmez.
- AralıkLı: Öğeler hem her öğe arasında hem de satırın başında ve sonunda eşit miktarda boşlukla eşit bir şekilde dağıtılır.
Bu görüntüde , ItemsStretch değerlerinin dikey düzendeki (satırlar yerine sütunlara uygulanır) etkisi gösterilir.
İpucu
ItemsStretch özelliği, düzenin ölçü geçişini etkiler. ItemsJustification özelliği, düzenin düzenleme geçişini etkiler.
Bu örnekte ItemsRepeater.Layout özelliğinin UniformGridLayout olarak nasıl ayarlanacağı gösterilmektedir.
<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<muxc:ItemsRepeater ItemsSource="{x:Bind Items}"
ItemTemplate="{StaticResource MyTemplate}">
<muxc:ItemsRepeater.Layout>
<muxc:UniformGridLayout MinItemWidth="200"
MinColumnSpacing="28"
ItemsJustification="SpaceAround"/>
</muxc:ItemsRepeater.Layout>
</muxc:ItemsRepeater>
Yaşam döngüsü olayları
Öğeleri bir ItemsRepeater'da barındırırken, bir öğe gösterildiğinde veya gösterilmeyi durdurduğunda bazı içeriklerin zaman uyumsuz indirilmesini başlatma, öğeyi seçimi izlemek için bir mekanizmayla ilişkilendirme veya bazı arka plan görevini durdurma gibi bazı eylemler gerçekleştirmeniz gerekebilir.
Sanallaştırma denetiminde, öğe geri dönüştürülen canlı görsel ağacından kaldırılmayabileceği için Yüklenen/Kaldırılan olaylara güvenemezsiniz. Bunun yerine, öğelerin yaşam döngüsünü yönetmek için başka olaylar sağlanır. Bu diyagramda bir ItemsRepeater içindeki bir öğenin yaşam döngüsü ve ilgili olayların ne zaman tetiklenmiş olduğu gösterilir.
- ElementPrepared , bir öğe kullanıma hazır hale getirildiğinde gerçekleşir. Bu, hem yeni oluşturulan bir öğe hem de zaten var olan ve geri dönüşüm kuyruğundan yeniden kullanılan bir öğe için oluşur.
- ElementClearing, bir öğe geri dönüşüm kuyruğuna gönderildiği her defasında, örneğin gerçekleştirilmiş öğelerin aralığının dışına çıktığında, hemen gerçekleşir.
- ElemanDizinDeğişti, temsil ettiği öğenin indeksi değişen her oluşturulmuş UIElement için meydana gelir. Örneğin, veri kaynağına başka bir öğe eklendiğinde veya kaldırıldığında, sıralamadan sonra gelen öğelerin dizini bu olayı alır.
Bu örnekte, öğeleri görüntülemek için ItemsRepeater kullanan bir özel denetimde öğe seçimini izlemek üzere özel bir seçim hizmeti eklemek için bu olayları nasıl kullanabileceğiniz gösterilir.
<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<UserControl ...>
...
<ScrollViewer>
<muxc:ItemsRepeater ItemsSource="{x:Bind Items}"
ItemTemplate="{StaticResource MyTemplate}"
ElementPrepared="OnElementPrepared"
ElementIndexChanged="OnElementIndexChanged"
ElementClearing="OnElementClearing">
</muxc:ItemsRepeater>
</ScrollViewer>
...
</UserControl>
interface ISelectable
{
int SelectionIndex { get; set; }
void UnregisterSelectionModel(SelectionModel selectionModel);
void RegisterSelectionModel(SelectionModel selectionModel);
}
private void OnElementPrepared(ItemsRepeater sender, ElementPreparedEventArgs args)
{
var selectable = args.Element as ISelectable;
if (selectable != null)
{
// Wire up this item to recognize a 'select' and listen for programmatic
// changes to the selection model to know when to update its visual state.
selectable.SelectionIndex = args.Index;
selectable.RegisterSelectionModel(this.SelectionModel);
}
}
private void OnElementIndexChanged(ItemsRepeater sender, ElementIndexChangedEventArgs args)
{
var selectable = args.Element as ISelectable;
if (selectable != null)
{
// Sync the ID we use to notify the selection model when the item
// we represent has changed location in the data source.
selectable.SelectionIndex = args.NewIndex;
}
}
private void OnElementClearing(ItemsRepeater sender, ElementClearingEventArgs args)
{
var selectable = args.Element as ISelectable;
if (selectable != null)
{
// Disconnect handlers to recognize a 'select' and stop
// listening for programmatic changes to the selection model.
selectable.UnregisterSelectionModel(this.SelectionModel);
selectable.SelectionIndex = -1;
}
}
Verileri Sıralama, Filtreleme ve Sıfırlama
Veri kümenizi filtreleme veya sıralama gibi eylemler gerçekleştirdiğinizde, geleneksel olarak önceki veri kümesini yeni verilerle karşılaştırmış ve ardından INotifyCollectionChanged aracılığıyla ayrıntılı değişiklik bildirimleri yayımlamış olabilirsiniz. Ancak, eski verileri yeni verilerle tamamen değiştirmek ve bunun yerine Sıfırla eylemini kullanarak bir koleksiyon değişikliği bildirimi tetikleme genellikle daha kolaydır.
Genellikle sıfırlama, bir denetimin mevcut alt öğeleri serbest bırakmasına ve sıfırlama sırasında verilerin tam olarak nasıl değiştiği hakkında bir farkındalık olmadığından, kaydırma konumu 0'dan kullanıcı arabirimini baştan oluşturmasına neden olur.
Ancak, ItemsSource olarak atanan koleksiyon IKeyIndexMapping arabirimini uygulayarak benzersiz tanımlayıcıları destekliyorsa ItemsRepeater şunları hızla tanımlayabilir:
- sıfırlamadan önce ve sonra var olan veriler için yeniden kullanılabilir UIElement'ler
- kaldırılan önceden görünür öğeler
- görünür olacak yeni öğeler eklendi
Bu, ItemsRepeater'ın 0 kaydırma konumundan baştan başlamasını önler. Ayrıca, sıfırlamada değişmemiş veriler için UIElement'leri hızla geri yükleyerek daha iyi performans elde etmelerini sağlar.
Bu örnek, temel alınan bir öğe listesini saran MyItemsSource adlı özel bir veri kaynağının kullanıldığı dikey bir yığında, öğe listesinin nasıl görüntüleneceğini göstermektedir. Öğe kaynağı olarak kullanılacak yeni bir listeyi yeniden atamak için kullanılabilecek bir Data özelliğini kullanıma sunar ve ardından sıfırlama tetikler.
<ScrollViewer x:Name="sv">
<ItemsRepeater x:Name="repeater"
ItemsSource="{x:Bind MyItemsSource}"
ItemTemplate="{StaticResource MyTemplate}">
<ItemsRepeater.Layout>
<StackLayout ItemSpacing="8"/>
</ItemsRepeater.Layout>
</ItemsRepeater>
</ScrollViewer>
public MainPage()
{
this.InitializeComponent();
// Similar to an ItemsControl, a developer sets the ItemsRepeater's ItemsSource.
// Here we provide our custom source that supports unique IDs which enables
// ItemsRepeater to be smart about handling resets from the data.
// Unique IDs also make it easy to do things apply sorting/filtering
// without impacting any state (i.e. selection).
MyItemsSource myItemsSource = new MyItemsSource(data);
repeater.ItemsSource = myItemsSource;
// ...
// We can sort/filter the data using whatever mechanism makes the
// most sense (LINQ, database query, etc.) and then reassign
// it, which in our implementation triggers a reset.
myItemsSource.Data = someNewData;
}
// ...
public class MyItemsSource : IReadOnlyList<ItemBase>, IKeyIndexMapping, INotifyCollectionChanged
{
private IList<ItemBase> _data;
public MyItemsSource(IEnumerable<ItemBase> data)
{
if (data == null) throw new ArgumentNullException();
this._data = data.ToList();
}
public IList<ItemBase> Data
{
get { return _data; }
set
{
_data = value;
// Instead of tossing out existing elements and re-creating them,
// ItemsRepeater will reuse the existing elements and match them up
// with the data again.
this.CollectionChanged?.Invoke(
this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
#region IReadOnlyList<T>
public ItemBase this[int index] => this.Data != null
? this.Data[index]
: throw new IndexOutOfRangeException();
public int Count => this.Data != null ? this.Data.Count : 0;
public IEnumerator<ItemBase> GetEnumerator() => this.Data.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
#endregion
#region INotifyCollectionChanged
public event NotifyCollectionChangedEventHandler CollectionChanged;
#endregion
#region IKeyIndexMapping
private int lastRequestedIndex = IndexNotFound;
private const int IndexNotFound = -1;
// When UniqueIDs are supported, the ItemsRepeater caches the unique ID for each item
// with the matching UIElement that represents the item. When a reset occurs the
// ItemsRepeater pairs up the already generated UIElements with items in the data
// source.
// ItemsRepeater uses IndexForUniqueId after a reset to probe the data and identify
// the new index of an item to use as the anchor. If that item no
// longer exists in the data source it may try using another cached unique ID until
// either a match is found or it determines that all the previously visible items
// no longer exist.
public int IndexForUniqueId(string uniqueId)
{
// We'll try to increase our odds of finding a match sooner by starting from the
// position that we know was last requested and search forward.
var start = lastRequestedIndex;
for (int i = start; i < this.Count; i++)
{
if (this[i].PrimaryKey.Equals(uniqueId))
return i;
}
// Then try searching backward.
start = Math.Min(this.Count - 1, lastRequestedIndex);
for (int i = start; i >= 0; i--)
{
if (this[i].PrimaryKey.Equals(uniqueId))
return i;
}
return IndexNotFound;
}
public string UniqueIdForIndex(int index)
{
var key = this[index].PrimaryKey;
lastRequestedIndex = index;
return key;
}
#endregion
}
Özel koleksiyon denetimi oluşturma
ItemsRepeater kullanarak, her öğeyi sunan kendi denetim türüyle tamamlanmış özel bir koleksiyon denetimi oluşturabilirsiniz.
Uyarı
Bu, ItemsControlkullanmaya benzer, ancak ItemsControl yerine Control'dan türetip denetim şablonuna bir ItemsPresenter yerleştirmek yerine, denetim şablonuna bir ItemsRepeater yerleştirirsiniz. Özel koleksiyon denetimi "has an" ItemsRepeater ile "is an" ItemsControl. Bu, devralınan özelliklerin desteklenmemesinden ziyade, hangi özelliklerin kullanıma açılacağına açıkça karar vermeniz gerektiğini de ifade eder.
Bu örnek, ItemsRepeater'ı, MediaCollectionView adlı özel bir denetimin şablonuna yerleştirmeyi ve özelliklerini kullanıma sunmayı göstermektedir.
<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<Style TargetType="local:MediaCollectionView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MediaCollectionView">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer x:Name="ScrollViewer">
<muxc:ItemsRepeater x:Name="ItemsRepeater"
ItemsSource="{TemplateBinding ItemsSource}"
ItemTemplate="{TemplateBinding ItemTemplate}"
Layout="{TemplateBinding Layout}"
TabFocusNavigation="{TemplateBinding TabFocusNavigation}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
public sealed class MediaCollectionView : Control
{
public object ItemsSource
{
get { return (object)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(MediaCollectionView), new PropertyMetadata(0));
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemTemplate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemTemplateProperty =
DependencyProperty.Register(nameof(ItemTemplate), typeof(DataTemplate), typeof(MediaCollectionView), new PropertyMetadata(0));
public Layout Layout
{
get { return (Layout)GetValue(LayoutProperty); }
set { SetValue(LayoutProperty, value); }
}
// Using a DependencyProperty as the backing store for Layout. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LayoutProperty =
DependencyProperty.Register(nameof(Layout), typeof(Layout), typeof(MediaCollectionView), new PropertyMetadata(0));
public MediaCollectionView()
{
this.DefaultStyleKey = typeof(MediaCollectionView);
}
}
Gruplandırılmış öğeleri görüntüleme
bir ItemsRepeater'ı, iç içe sanallaştırma düzenleri oluşturmak için başka bir ItemsRepeater öğesinin ItemTemplate'ine yerleştirebilirsiniz. Çerçeve, görünür olmayan veya geçerli görünüm penceresine yakın öğelerin gereksiz şekilde gerçekleştirilmesini en aza indirerek kaynakların verimli bir şekilde kullanılmasını sağlayacaktır.
Bu örnek, gruplandırılmış öğelerin listesini dikey yığında nasıl görüntüleyebileceğinizi gösterir. Dıştaki ItemsRepeater her grubu oluşturur. Her grubun şablonunda, öğeleri başka bir ItemsRepeater oluşturur.
<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<Page.Resources>
<muxc:StackLayout x:Key="MyGroupLayout"/>
<muxc:StackLayout x:Key="MyItemLayout" Orientation="Horizontal"/>
</Page.Resources>
<ScrollViewer>
<muxc:ItemsRepeater ItemsSource="{x:Bind AppNotifications}"
Layout="{StaticResource MyGroupLayout}">
<muxc:ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="ExampleApp:AppNotifications">
<!-- Group -->
<StackPanel>
<!-- Header -->
<TextBlock Text="{x:Bind AppTitle}"/>
<!-- Items -->
<muxc:ItemsRepeater ItemsSource="{x:Bind Notifications}"
Layout="{StaticResource MyItemLayout}"
ItemTemplate="{StaticResource MyTemplate}"/>
<!-- Footer -->
<Button Content="{x:Bind FooterText}"/>
</StackPanel>
</DataTemplate>
</muxc:ItemsRepeater.ItemTemplate>
</muxc:ItemsRepeater>
</ScrollViewer>
Aşağıdaki görüntüde, kılavuz olarak yukarıdaki örnek kullanılarak oluşturulan temel düzen gösterilmektedir.
Bu sonraki örnekte, kullanıcı tercihiyle değişebilen ve yatay olarak kayan listeler olarak sunulan çeşitli kategorilere sahip bir uygulamanın düzeni gösterilir. Bu örneğin düzeni de yukarıdaki görüntüyle temsil edilir.
<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<!-- Include the <muxc:ItemsRepeaterScrollHost> if targeting Windows 10 versions earlier than 1809. -->
<ScrollViewer>
<muxc:ItemsRepeater ItemsSource="{x:Bind Categories}"
Background="LightGreen">
<muxc:ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="local:Category">
<StackPanel Margin="12,0">
<TextBlock Text="{x:Bind Name}" Style="{ThemeResource TitleTextBlockStyle}"/>
<!-- Include the <muxc:ItemsRepeaterScrollHost> if targeting Windows 10 versions earlier than 1809. -->
<ScrollViewer HorizontalScrollMode="Enabled"
VerticalScrollMode="Disabled"
HorizontalScrollBarVisibility="Auto" >
<muxc:ItemsRepeater ItemsSource="{x:Bind Items}"
Background="Orange">
<muxc:ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="local:CategoryItem">
<Grid Margin="10"
Height="60" Width="120"
Background="LightBlue">
<TextBlock Text="{x:Bind Name}"
Style="{StaticResource SubtitleTextBlockStyle}"
Margin="4"/>
</Grid>
</DataTemplate>
</muxc:ItemsRepeater.ItemTemplate>
<muxc:ItemsRepeater.Layout>
<muxc:StackLayout Orientation="Horizontal"/>
</muxc:ItemsRepeater.Layout>
</muxc:ItemsRepeater>
</ScrollViewer>
</StackPanel>
</DataTemplate>
</muxc:ItemsRepeater.ItemTemplate>
</muxc:ItemsRepeater>
</ScrollViewer>
Öğeyi Görünüme Getirme
XAML çerçevesi, 1) klavye odağı veya 2) Narrator odağı aldığında bir FrameworkElement'in görünüme getirilmesini zaten yönetir. Bir öğeyi açıkça görünüme getirmeniz gereken başka durumlar da olabilir. Örneğin, bir kullanıcı eylemine yanıt olarak veya sayfa gezintisi sonrasında kullanıcı arabiriminin durumunu geri yüklemek için.
Sanallaştırılmış bir öğenin görünüme getirilmesi aşağıdakileri içerir:
- Bir öğe için UIElement oluşturma
- Öğenin geçerli bir konumu olduğundan emin olmak için düzeni çalıştırın
- Gerçekleştirilen öğeyi görünüme getirmek için bir istek başlatma
Aşağıdaki örnekte, sayfa gezintisi sonrasında düz, dikey bir listedeki bir öğenin kaydırma konumunu geri yüklemenin bir parçası olarak bu adımlar gösterilmektedir. İç içe ItemsRepeaters kullanan hiyerarşik veriler söz konusu olduğunda yaklaşım temelde aynıdır, ancak hiyerarşinin her düzeyinde yapılmalıdır.
<ScrollViewer x:Name="scrollviewer">
<ItemsRepeater x:Name="repeater" .../>
</ScrollViewer>
public class MyPage : Page
{
// ...
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// retrieve saved offset + index(es) of the tracked element and then bring it into view.
// ...
var element = repeater.GetOrCreateElement(index);
// ensure the item is given a valid position
element.UpdateLayout();
element.StartBringIntoView(new BringIntoViewOptions()
{
VerticalOffset = relativeVerticalOffset
});
}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
// retrieve and save the relative offset and index(es) of the scrollviewer's current anchor element ...
var anchor = this.scrollviewer.CurrentAnchor;
var index = this.repeater.GetElementIndex(anchor);
var anchorBounds = anchor.TransformToVisual(this.scrollviewer).TransformBounds(new Rect(0, 0, anchor.ActualSize.X, anchor.ActualSize.Y));
relativeVerticalOffset = this.scrollviewer.VerticalOffset - anchorBounds.Top;
}
}
Erişilebilirliği Etkinleştir
ItemsRepeater varsayılan bir erişilebilirlik deneyimi sağlamaz. Windows uygulamaları için Kullanılabilirlik belgeleri, uygulamanızın kapsayıcı bir kullanıcı deneyimi sağladığından emin olmanıza yardımcı olacak zengin bilgiler sağlar. Özel denetim oluşturmak için ItemsRepeater kullanıyorsanız Özel otomasyon eşleribelgelerine bakın.
Klavye
ItemsRepeater'ın sağladığı odak hareketi için minimum klavye desteği, XAML'nin klavyeiçin
ItemsRepeater'ın
ItemsRepeater, öğeleri için varsayılan sekme sırasının (sanallaştırılmış olsun veya olmasın) verilerde verilen öğelerin sırasının aynısını izlediğinden otomatik olarak emin olur. Varsayılan olarak ItemsRepeater'ın TabFocusNavigation özelliği, yaygın varsayılan olan Yerelyerine Bir kez olarak ayarlanmıştır.
Uyarı
ItemsRepeater, odaklanmış son öğeyi otomatik olarak anımsamıyor. Bu, bir kullanıcı Shift+Sekme tuşlarını kullandığında, son gerçekleştirilen öğeye alınabileceği anlamına gelir.
Ekran Okuyucular'da "Y'in numaralı numaralı öğesi" açıklanıyor
PositionInSet ve SizeOfSetdeğerleri gibi uygun otomasyon özelliklerini ayarlamayı yönetmeniz ve öğeler eklendiğinde, taşındığında, kaldırıldığında vb. up-togüncel kaldığından emin olmanız gerekir.
Bazı özel düzenlerde görsel sırasının belirgin bir sırası olmayabilir. Kullanıcılar, ekran okuyucuların kullandığı PositionInSet ve SizeOfSet özelliklerine ait değerlerin, öğelerin verilerde görünme sırasıyla (doğal saymaya uygun olarak 0 tabanlı yerine 1'den başlayacak şekilde) eşleşmesini bekler.
Bunu başarmak için en iyi yol, öğe denetimi için otomasyon eşlerinin GetPositionInSetCore
Bu örnek , CardControl adlı özel bir denetim sunarken bunu nasıl yapabileceğinizi gösterir.
<ScrollViewer >
<ItemsRepeater x:Name="repeater" ItemsSource="{x:Bind MyItemsSource}">
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="local:CardViewModel">
<local:CardControl Item="{x:Bind}"/>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>
internal sealed class CardControl : CardControlBase
{
protected override AutomationPeer OnCreateAutomationPeer() => new CardControlAutomationPeer(this);
private sealed class CardControlAutomationPeer : FrameworkElementAutomationPeer
{
private readonly CardControl owner;
public CardControlAutomationPeer(CardControl owner) : base(owner) => this.owner = owner;
protected override int GetPositionInSetCore()
=> ((ItemsRepeater)owner.Parent)?.GetElementIndex(this.owner) + 1 ?? base.GetPositionInSetCore();
protected override int GetSizeOfSetCore()
=> ((ItemsRepeater)owner.Parent)?.ItemsSourceView?.Count ?? base.GetSizeOfSetCore();
}
}
UWP ve WinUI 2
Önemli
Bu makaledeki bilgiler ve örnekler, Windows Uygulama SDK'sı ve WinUI 3kullanan uygulamalar için iyileştirilmiştir, ancak genellikle WinUI 2kullanan UWP uygulamaları için geçerlidir. Platforma özgü bilgiler ve örnekler için UWP API başvurusuna bakın.
Bu bölüm, denetimi bir UWP veya WinUI 2 uygulamasında kullanmak için ihtiyacınız olan bilgileri içerir.
UWP uygulamaları için ItemsRepeater, WinUI 2 gerektirir. Yükleme yönergeleri de dahil olmak üzere daha fazla bilgi için bkz. WinUI 2. Bu denetimin API'leri Microsoft.UI.Xaml.Controls ad alanında bulunur.
- UWP API'leri:ScrollViewer sınıfı
- WinUI 2 API'leri :ItemsRepeater sınıfı
- WinUI 2 Gallery uygulamasını açın ve ItemsRepeater'ı çalışırken görün. WinUI 2 Galeri uygulaması çoğu WinUI 2 denetimi, özelliği ve işlevselliğine ilişkin etkileşimli örnekler içerir. Uygulamayı Microsoft Store'dan alın veya GitHub'dan kaynak kodunu alın.
Bu makaledeki kodu WinUI 2 ile kullanmak için, projenize dahil edilen Windows UI Kitaplığı API'lerini temsil etmek için XAML'de bir diğer ad kullanın (muxckullanıyoruz). Daha fazla bilgi için WinUI 2'yi kullanmaya başlama hakkında bölümüne bakın.
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:ItemsRepeater />
İlgili makaleler
Windows developer