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.
Bu makalede , Microsoft.UI.Xaml.Data ad alanında API'leri kullanan WinUI veri bağlama özellikleri açıklanmaktadır.
Uyarı
Bu konu başlığında veri bağlama özellikleri ayrıntılı olarak açıklanmaktadır. Kısa ve pratik bir giriş için bkz. Veri bağlamaya genel bakış.
Önemli API'ler
Giriş
Veri bağlama, uygulamanızın kullanıcı arabiriminin verileri verimli bir şekilde görüntülemesine ve eşitlemesine olanak tanıyan bir tekniktir. Veri endişelerini kullanıcı arabirimi endişelerinden ayırarak uygulama tasarımını basitleştirir, okunabilirliği artırır ve sürdürülebilirliği geliştirir.
Veri bağlamayı, kullanıcı arabirimi ilk kez gösterildiğinde bir veri kaynağındaki değerleri görüntülemek için kullanabilirsiniz, ancak bu değerlerdeki değişikliklere yanıt vermek için kullanamazsınız. Bu bağlama modu tek seferlik olarak adlandırılır ve çalışma zamanı sırasında değişmeyen bir değer için iyi çalışır. Alternatif olarak, değerleri "gözlemlemeyi" ve değiştiğinde kullanıcı arabirimini güncelleştirmeyi seçebilirsiniz. Bu mod tek yönlü olarak adlandırılır ve salt okunur veriler için iyi çalışır. Sonuç olarak, kullanıcının kullanıcı arabirimindeki değerlerde yaptığı değişikliklerin otomatik olarak veri kaynağına geri gönderilmesi için hem gözlemlemeyi hem de güncelleştirmeyi seçebilirsiniz. Bu mod iki yönlü olarak adlandırılır ve okuma-yazma verileri için iyi çalışır. Aşağıda bazı örnekler verilmiştir.
- Mevcut kullanıcının fotoğrafına bir Resim bağlamak için tek seferlik modu kullanabilirsiniz.
- ListView'ı gazete bölümüne göre gruplandırılmış gerçek zamanlı haber makalelerinden oluşan bir koleksiyona bağlamak için tek yönlü modu kullanabilirsiniz.
- TextBox'ı bir formdaki müşterinin adına bağlamak için iki yönlü modu kullanabilirsiniz.
Moddan bağımsız olarak iki bağlama türü vardır ve genellikle her ikisini de ui işaretlemesinde bildirirsiniz.
{x:Bind} işaretleme uzantısını veya {Binding} işaretleme uzantısını kullanmayı seçebilirsiniz. Hatta aynı uygulamada, aynı kullanıcı arabirimi öğesinde bile ikisinin bir karışımını kullanabilirsiniz.
{x:Bind} Windows 10 için UWP'de yeniydi ve daha iyi performansa sahip. Bu konuda açıklanan tüm ayrıntılar, açıkça aksini söylemediğimiz sürece her iki bağlama türü için de geçerlidir.
{x:Bind} gösteren UWP örnek uygulamaları
{Binding} gösteren UWP örnek uygulamaları
- UWP Bookstore1 uygulamasını indirin.
- Bookstore2 uygulamasını indirin.
Her bağlama bu parçaları içerir
- Bağlama kaynağı. Bu kaynak bağlama için verileri sağlar. Kullanıcı arabiriminizde değerlerini görüntülemek istediğiniz üyeleri olan herhangi bir sınıfın örneği olabilir.
- Bağlama hedefi. Bu hedef, verileri görüntüleyen kullanıcı arabiriminizdeki FrameworkElement'in DependencyProperty özelliğidir.
- Bağlama nesnesi. Bu nesne veri değerlerini kaynaktan hedefe ve isteğe bağlı olarak hedeften kaynağa aktarır. Bağlama nesnesi XAML yükleme zamanında {x:Bind} veya {Binding} işaretleme uzantınızdan oluşturulur.
Aşağıdaki bölümlerde bağlama kaynağına, bağlama hedefini ve bağlama nesnesine daha yakından bakacaksınız. Bölümler, bir düğmenin içeriğini adlı NextButtonTextsınıfa ait olan adlı HostViewModeldize özelliğine bağlama örneğiyle birbirine bağlanır.
Bağlama kaynağı
Bağlama kaynağı olarak kullanabileceğiniz temel bir sınıf uygulaması aşağıdadır.
public class HostViewModel
{
public HostViewModel()
{
NextButtonText = "Next";
}
public string NextButtonText { get; set; }
}
bu uygulaması HostViewModelve özelliği NextButtonTextyalnızca bir kerelik bağlama için çalışır. Ancak tek yönlü ve iki yönlü bağlamalar son derece yaygındır. Bu bağlama türlerinde kullanıcı arabirimi, bağlama kaynağının veri değerlerindeki değişikliklere yanıt olarak otomatik olarak güncelleştirilir. Bu bağlama türlerinin doğru çalışması için bağlama kaynağınızı bağlama nesnesine göre gözlemlenebilir hale getirmeniz gerekir. Bu nedenle örneğimizde, özelliğe tek yönlü veya iki yönlü bağlama NextButtonText yapmak istiyorsanız, çalışma zamanında bu özelliğin değerinde gerçekleşen tüm değişikliklerin bağlama nesnesine gözlemlenebilir olması gerekir.
Bunu yapmanızın bir yolu, dependencyObject'ten bağlama kaynağınızı temsil eden sınıfı türetmek ve DependencyProperty* aracılığıyla bir veri değeri ortaya çıkarmaktır.
FrameworkElement bu şekilde gözlemlenebilir hale gelir. A FrameworkElement , kutudan çıktığı anda iyi bir bağlama kaynağıdır.
Sınıfı gözlemlenebilir hale getirmenin daha basit bir yolu ve zaten bir temel sınıfı olan sınıflar için gerekli olan, System.ComponentModel.INotifyPropertyChanged uygulamaktır. Bu yaklaşım, adlı PropertyChangedtek bir olay uygulamayı içerir. Kullanan HostViewModel bir örnek aşağıdaki kodda gösterilmiştir.
...
using System.ComponentModel;
using System.Runtime.CompilerServices;
...
public class HostViewModel : INotifyPropertyChanged
{
private string nextButtonText;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public HostViewModel()
{
NextButtonText = "Next";
}
public string NextButtonText
{
get { return nextButtonText; }
set
{
nextButtonText = value;
OnPropertyChanged();
}
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// Raise the PropertyChanged event, passing the name of the property whose value has changed.
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
NextButtonText Artık özelliği gözlemlenebilir. Bu özelliğe tek yönlü veya iki yönlü bağlama yazdığınızda (daha sonra göstereceğiz), sonuçta elde edilen bağlama nesnesi olaya abone olur PropertyChanged . Bu olay tetiklendiğinde, bağlama nesnesinin işleyicisi değiştirilen özelliğin adını içeren bir bağımsız değişken alır. Bağlama nesnesi, hangi özelliğin değerinin yeniden okunmasını bu şekilde bilir.
Daha önce gösterilen deseni birden çok kez uygulamanız gerekmemesi için, C# kullanıyorsanız BindableBase örneğinde ("Ortak" klasöründe) bulabileceğiniz temel sınıftan türetebilirsiniz. Bunun nasıl göründüğüne dair bir örnek aşağıda verilmiştır.
public class HostViewModel : BindableBase
{
private string nextButtonText;
public HostViewModel()
{
NextButtonText = "Next";
}
public string NextButtonText
{
get { return nextButtonText; }
set { SetProperty(ref nextButtonText, value); }
}
}
PropertyChanged olayını String.Empty argümanı ile tetiklemek veya null, nesnedeki dizin oluşturucu olmayan tüm özelliklerin yeniden okunması gerektiğini gösterir. Belirli dizin oluşturucular için "Item[indexer]" bağımsız değişkenini (dizin oluşturucunun dizin değeri olduğu) veya tüm dizin oluşturucular için "Öğe[]" değerini kullanarak nesnedeki dizin oluşturucu özelliklerinin değiştiğini belirtmek için olayı tetikleyebilirsiniz.
Bağlama kaynağını, özellikleri veri içeren tek bir nesne olarak veya nesne koleksiyonu olarak değerlendirebilirsiniz. C# kodunda, çalışma zamanında değişmeyen bir koleksiyonu görüntülemek için List<T> uygulayan bir nesneye tek seferlik bağlanabilirsiniz. Gözlemlenebilir bir koleksiyon için (öğeler koleksiyona eklendiğinde ve koleksiyondan kaldırıldığında gözlemleme), bunun yerine ObservableCollection<T'ye> tek yönlü bağlama. Kendi koleksiyon sınıflarınıza bağlanmak için aşağıdaki tabloda yer alan yönergeleri kullanın.
| Scenario | C# (CLR) | C++/WinRT |
|---|---|---|
| Bir nesneye bağlama. | Herhangi bir nesne olabilir. | Herhangi bir nesne olabilir. |
| İlişkili bir nesneden özellik değişikliği bildirimleri alma. | Nesnenin INotifyPropertyChanged uygulaması gerekir. | Nesnenin INotifyPropertyChanged uygulaması gerekir. |
| Bir koleksiyona bağlama. | Liste<T> | IInspectable veya IBindableObservableVector'ın IVector'ı. Bkz . XAML öğeleri denetimleri; C++/WinRT koleksiyonuna bağlama ve C++/WinRT ile Koleksiyonlar. |
| İlişkili bir koleksiyondan koleksiyon değişikliği bildirimleri alma. | ObservableCollection<T> | IInspectable'ın IObservableVector'ı. Örneğin, winrt::single_threaded_observable_vector<T>. |
| Bağlamayı destekleyen bir koleksiyon uygulayın. | IList<T> ve IEnumerable<T> öğelerine bağlanma desteklenmez. |
IInspectable'ınIVector'ını uygulayın. Bkz . XAML öğeleri denetimleri; C++/WinRT koleksiyonuna bağlama ve C++/WinRT ile Koleksiyonlar. |
| Koleksiyon değişikliği bildirimlerini destekleyen bir koleksiyon uygulayın. | ObservableCollection<T'yi> genişletin veya (genel olmayan) IList ve INotifyCollectionChanged uygulayın. | IInspectable veya IBindableObservableVector için IObservableVector uygulayın. |
| Artımlı yüklemeyi destekleyen bir koleksiyon uygulayın. | ObservableCollection<T'yi> genişletin veya (genel olmayan) IList ve INotifyCollectionChanged uygulayın. Ayrıca , ISupportIncrementalLoading'i uygulayın. | IInspectable veya IBindableObservableVector için IObservableVector uygulayın. Ayrıca, ISupportIncrementalLoading'i uygulayın |
Artımlı yükleme kullanarak liste denetimlerini rastgele büyük veri kaynaklarına bağlayabilir ve yine de yüksek performans elde edebilirsiniz. Örneğin, tüm sonuçları aynı anda yüklemek zorunda kalmadan liste denetimlerini Bing resim sorgusu sonuçlarına bağlayabilirsiniz. Bunun yerine, yalnızca bazı sonuçları hemen yüklersiniz ve gerektiğinde ek sonuçlar yüklersiniz. Artımlı yüklemeyi desteklemek için, koleksiyon değişikliği bildirimlerini destekleyen bir veri kaynağına ISupportIncrementalLoading uygulamanız gerekir. Veri bağlama altyapısı daha fazla veri istediğinde, veri kaynağınızın uygun istekleri yapması, sonuçları tümleştirmesi ve ardından kullanıcı arabirimini güncelleştirmek için uygun bildirimleri göndermesi gerekir.
Hedef bağlama
Aşağıdaki iki örnekte Button.Content özelliği bağlama hedefidir. Değeri, bağlama nesnesini bildiren bir işaretleme uzantısına ayarlanır. İlk örnekte {x:Bind} ve ikinci örnekte {Binding} gösterilmektedir. İşaretlemede bağlamaların bildirilmesi yaygın bir durumdur çünkü kullanışlı, okunabilir ve araçlanabilirdir. Ancak gerekirse, işaretlemeyi önleyebilir ve zorunlu olarak (program aracılığıyla) binding sınıfının bir örneğini oluşturabilirsiniz.
<Button Content="{x:Bind ...}" ... />
<Button Content="{Binding ...}" ... />
C++/WinRT kullanıyorsanız, {Binding} işaretleme uzantısını kullanmak istediğiniz herhangi bir çalışma zamanı sınıfına BindableAttribute özniteliğini eklemeniz gerekir.
Önemli
C++/WinRT kullanıyorsanız BindableAttribute özniteliği Windows Uygulama SDK'sı ile kullanılabilir. Bu öznitelik olmadan, {Binding} işaretleme uzantısını kullanabilmek için ICustomPropertyProvider ve ICustomProperty arabirimlerini uygulamanız gerekir.
{x:Bind} kullanılarak bildirilen bağlama nesnesi
{x:Bind} işaretlemenizi yazmadan önce, biçimlendirme sayfanızı temsil eden sınıftan bağlama kaynak sınıfınızı kullanıma sunmanız gerekir. Pencere sınıfınıza (bu durumda HostViewModel türünde bir özellik) ekleyin.
namespace DataBindingInDepth
{
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
ViewModel = new HostViewModel();
}
public HostViewModel ViewModel { get; set; }
}
}
özelliğini ekledikten sonra bağlama nesnesini bildiren işaretlemeye daha yakından bakabilirsiniz. Aşağıdaki örnek, daha önce "Bağlama hedefi" bölümünde gördüğünüz bağlama hedefinin aynısını Button.Content kullanır. Bağlama hedefinin HostViewModel.NextButtonText özelliğine olarak bağlı olduğunu gösterir.
<!-- MainWindow.xaml -->
<Window x:Class="DataBindingInDepth.MainWindow" ... >
<Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
</Window>
için Pathbelirttiğiniz değere dikkat edin. Pencere bu değeri kendi bağlamında yorumlar. Bu durumda yol, yeni eklediğiniz ViewModel özelliğine MainWindow sayfasında başvurarak başlar. Bu özellik bir HostViewModel örnek döndürür, böylece özelliğe erişmek için bu nesnenin içine HostViewModel.NextButtonText getirebilirsiniz.
Mode Bir kerelik {x:Bind} varsayılanını geçersiz kılmayı belirtirsiniz.
Path özelliği iç içe özelliklere, ekli özelliklere ve tamsayı ve dize dizin oluşturucularına bağlama için çeşitli söz dizimi seçeneklerini destekler. Daha fazla bilgi için bkz . Özellik yolu söz dizimi. Dize dizin oluşturucularına bağlama, ICustomPropertyProvider uygulamak zorunda kalmadan dinamik özelliklere bağlamanın etkisini sağlar. Diğer ayarlar için bkz. {x:Bind} işaretleme uzantısı.
Özelliğin HostViewModel.NextButtonText gözlemlenebilir olduğunu göstermek için bir Click olay işleyicisini düğme üzerine ekleyin ve HostViewModel.NextButtonText değerini güncelleyin. Düğme güncelleştirmesinin değerini görmek için derleyin, çalıştırın ve düğmeye Content tıklayın.
// MainWindow.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
ViewModel.NextButtonText = "Updated Next button text";
}
Uyarı
TextBox.Text dosyasındaki değişiklikler, TextBox her kullanıcı tuş vuruşu sonrasında değil, odağı kaybettiğinde iki yönlü bağlı kaynağa gönderilir.
DataTemplate ve x:DataType
DataTemplate içinde (öğe şablonu, içerik şablonu veya üst bilgi şablonu olarak kullansanız da), Path değeri pencere bağlamında yorumlanmaz. Bunun yerine, şablon oluşturduğunuz veri nesnesi bağlamında çalışır. Veri şablonunda kullandığınızda {x:Bind} , bağlamalarını derleme zamanında doğrulayabilir ve bunlar için verimli kod oluşturabilirsiniz. Bunu yapmak için, DataTemplate veri nesnesinin türünü kullanarak x:DataTypebildirmesi gerekir. Aşağıdaki örnek, bir nesne koleksiyonuna ItemTemplateSampleDataGroup bağlı bir öğe denetimi olarak kullanılabilir.
<DataTemplate x:Key="SimpleItemTemplate" x:DataType="data:SampleDataGroup">
<StackPanel Orientation="Vertical" Height="50">
<TextBlock Text="{x:Bind Title}"/>
<TextBlock Text="{x:Bind Description}"/>
</StackPanel>
</DataTemplate>
Yolunuzdaki zayıf türemiş nesneler
SampleDataGroup adlı, Title adında bir dize özelliği uygulayan bir türe sahip olduğunuzu varsayalım. Türü object olan bir MainWindow.SampleDataGroupAsObject özelliğiniz de var, ancak aslında bir SampleDataGroup örneği döndürüyor.
<TextBlock Text="{x:Bind SampleDataGroupAsObject.Title}"/> bağlama, object türünde Title özelliği bulunamadığından derleme hatasıyla sonuçlanır. Bu hatayı düzeltmek için Path söz diziminize şöyle bir dönüştürme ekleyin: <TextBlock Text="{x:Bind ((data:SampleDataGroup)SampleDataGroupAsObject).Title}"/>. Burada olarak bildirildiği Element ancak aslında bir olduğu başka bir objectörnek aşağıda verilmiştir: TextBlock.<TextBlock Text="{x:Bind Element.Text}"/> Yama hatayı düzeltir: <TextBlock Text="{x:Bind ((TextBlock)Element).Text}"/>.
Verileriniz zaman uyumsuz olarak yüklenirse
Windows'unuzun kısmi sınıfları derleme zamanında {x:Bind}'ü desteklemek için kod oluşturur. Bu dosyaları klasörünüzde obj (C#için) <view name>.g.csgibi adlarla bulabilirsiniz. Oluşturulan kod, pencerenizin Yükleme olayı için bir işleyici içerir. Bu işleyici, pencerenizin bağlamalarını temsil eden oluşturulan bir sınıftaki Initialize yöntemini çağırır.
Initialize, bağlantı kaynağı ile hedef arasında veri aktarımına başlamak için Update'i çağırır.
Loading , pencerenin veya kullanıcı denetiminin ilk ölçü geçişinin hemen öncesinde oluşturulur. Verileriniz zaman uyumsuz olarak yükleniyorsa, Initialize çağrılmadan önce hazır olmayabilir. Verileri yükledikten sonra, this.Bindings.Update(); çağırarak tek seferlik bağlamaları başlatabilirsiniz. Zaman uyumsuz olarak yüklenen veriler için yalnızca bir kerelik bağlamalara ihtiyacınız varsa, bunları bu şekilde başlatmak, tek yönlü bağlamalara sahip olmak ve değişiklikleri dinlemekten çok daha ucuzdur. Verileriniz ayrıntılı değişikliklere uğramıyorsa ve belirli bir işlemle güncellenebiliyorsa, bağlamalarınızı bir kerelik yapabilir ve Update çağrısıyla istediğiniz zaman elle güncelleştirmeyi zorlayabilirsiniz.
Uyarı
{x:Bind} JSON nesnesinin sözlük yapısında gezinme veya ördek yazma gibi geç bağlı senaryolar için uygun değildir. "Ördek yazma", özellik adlarındaki sözcük temelli eşleşmelere göre yazmanın zayıf bir biçimidir ("eğer yürüyorsa, yüzüyorsa ve ördek gibi şarlatansa, o zaman ördektir"). Ördek yazma ile Age , özelliğine yönelik bir bağlama bir Person veya Wine nesnesinden eşit olarak memnun olur (bu türlerin her birinin bir Age özelliği olduğu varsayılır). Bu senaryolar için işaretleme uzantısını {Binding} kullanın.
{Binding} kullanılarak bildirilen bağlama nesnesi
C++/WinRT kullanıyorsanız, {Binding} işaretleme uzantısını kullanırken bağlamak istediğiniz herhangi bir çalışma zamanı sınıfına BindableAttribute özniteliğini ekleyin. {x:Bind} kullanmak için bu özniteliğe ihtiyacınız yoktur.
// HostViewModel.idl
// Add this attribute:
[Microsoft.UI.Xaml.Data.Bindable]
runtimeclass HostViewModel : Microsoft.UI.Xaml.Data.INotifyPropertyChanged
{
HostViewModel();
String NextButtonText;
}
Önemli
C++/WinRT kullanıyorsanız BindableAttribute özniteliği Windows Uygulama SDK'sı ile kullanılabilir. Bu öznitelik olmadan, {Binding} işaretleme uzantısını kullanabilmek için ICustomPropertyProvider ve ICustomProperty arabirimlerini uygulamanız gerekir.
Varsayılan olarak , {Binding} işaretleme pencerenizin DataContext'ine bağlandığınızı varsayar. Bu nedenle, pencerenizin DataContext ayarını bağlama kaynak sınıfınızdan bir örnek olacak şekilde yapın (bu örnekte türü HostViewModel). Aşağıdaki örnek, bağlama nesnesini bildiren işaretlemeyi gösterir. Daha önce "Bağlama hedefi" bölümünde kullanılan Button.Content bağlama hedefini kullanır ve HostViewModel.NextButtonText özelliğine bağlanır.
<Window xmlns:viewmodel="using:DataBindingInDepth" ... >
<Window.DataContext>
<viewmodel:HostViewModel x:Name="viewModelInDataContext"/>
</Window.DataContext>
...
<Button Content="{Binding Path=NextButtonText}" ... />
</Window>
// MainWindow.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
viewModelInDataContext.NextButtonText = "Updated Next button text";
}
için Pathbelirtilen değere dikkat edin. Pencerenin DataContext değeri yorumlanır ve bu örnekte örneği HostViewModelolarak ayarlanır. yol özelliğine başvurur HostViewModel.NextButtonText .
Mode öğesini atlayabilirsiniz, çünkü tek yönlü {Binding} varsayılanı burada çalışır.
Kullanıcı arabirimi öğesi için Varsayılan DataContext değeri, üst öğesinin devralınan değeridir. Bu varsayılan ayarı, DataContext öğesini açıkça ayarlayarak geçersiz kılabilirsiniz, bu ayar da varsayılan olarak alt öğeler tarafından devralınır. Bir öğede açıkça ayar DataContext yapmak, aynı kaynağı kullanan birden çok bağlamaya sahip olmak istediğinizde kullanışlıdır.
Bağlama nesnesinin, bağlamanın bildirildiği UI öğesinin Source değerine varsayılan olarak atan bir özelliği vardır. Bu varsayılan ayarı , veya SourceRelativeSource bağlamada açıkça geçersiz ElementNamekılabilirsiniz (ayrıntılar için bkz. {Binding}).
DataTemplate içinde DataContext otomatik olarak şablonlanan veri nesnesine ayarlanır. Aşağıdaki örnek, ItemTemplate olarak kullanılarak, herhangi bir türdeki Title ve Description adlı dize özelliklerine sahip bir koleksiyona bağlı bir öğeler denetimi olabilir.
<DataTemplate x:Key="SimpleItemTemplate">
<StackPanel Orientation="Vertical" Height="50">
<TextBlock Text="{Binding Title}"/>
<TextBlock Text="{Binding Description"/>
</StackPanel>
</DataTemplate>
Uyarı
Varsayılan olarak, TextBox.Text'de yapılan değişiklikler TextBox odağı kaybettiğinde iki yönlü bağlı bir kaynağa gönderilir. Her kullanıcı tuş vuruşu sonrasında değişikliklerin gönderilmesine neden olmak içinUpdateSourceTrigger, işaretlemedeki bağlamada olarak ayarlayınPropertyChanged. Ayrıca olarak ayarlayarak UpdateSourceTriggerExplicit, değişikliklerin kaynağa ne zaman gönderileceğini tamamen denetleyebilirsiniz. Daha sonra metin kutusundaki olayları işlersiniz (genellikle TextBox.TextChanged), bindingExpression nesnesi almak için hedefte GetBindingExpression çağrısı yapın ve son olarak veri kaynağını program aracılığıyla güncelleştirmek için BindingExpression.UpdateSource'u çağırın.
Path özelliği iç içe özelliklere, ekli özelliklere ve tamsayı ve dize dizin oluşturucularına bağlama için çeşitli söz dizimi seçeneklerini destekler. Daha fazla bilgi için bkz . Özellik yolu söz dizimi. Dize dizin oluşturucularına bağlama, ICustomPropertyProvider uygulamak zorunda kalmadan dinamik özelliklere bağlamanın etkisini sağlar. ElementName özelliği, öğeden öğeye bağlama için kullanışlıdır. RelativeSource özelliğinin çeşitli kullanımları vardır ve bunlardan biri ControlTemplate içindeki şablon bağlamaya daha güçlü bir alternatiftir. Diğer ayarlar için bkz . {Binding} işaretleme uzantısı ve Bağlama sınıfı.
Kaynak ve hedef aynı türde değilse ne olur?
Boole özelliğinin değerine göre kullanıcı arabirimi öğesinin görünürlüğünü denetlemek veya sayısal bir değerin aralığı veya eğiliminin işlevi olan bir renkle ui öğesini işlemek veya dize bekleyen bir UI öğesi özelliğinde tarih ve/veya saat değeri görüntülemek istiyorsanız, ardından değerleri bir türden diğerine dönüştürmeniz gerekir. Doğru çözümün, bağlama sınıfınızdan doğru türde başka bir özelliği kullanıma açmak ve dönüştürme mantığını kapsüllenmiş ve test edilebilir halde tutmak olduğu durumlar vardır. Ancak bu çözüm, çok sayıda veya çok sayıda kaynak ve hedef özellik birleşimine sahip olduğunuzda esnek veya ölçeklenebilir değildir. Bu durumda, birkaç seçeneğiniz vardır:
- kullanıyorsanız
{x:Bind}, bu dönüştürmeyi yapmak için doğrudan bir işleve bağlanabilirsiniz - Alternatif olarak, dönüştürmeyi gerçekleştirmek için tasarlanmış bir nesne olan bir değer dönüştürücüsü de belirtebilirsiniz
Değer Dönüştürücüleri
Burada, bir DateTime değerini ay içeren bir değere dönüştüren tek seferlik veya tek yönlü bağlamaya uygun bir string değer dönüştürücüsü bulunmaktadır. sınıfı IValueConverter uygular.
public class DateToStringConverter : IValueConverter
{
// Define the Convert method to convert a DateTime value to
// a month string.
public object Convert(object value, Type targetType,
object parameter, string language)
{
// value is the data from the source object.
DateTime thisDate = (DateTime)value;
int monthNum = thisDate.Month;
string month;
switch (monthNum)
{
case 1:
month = "January";
break;
case 2:
month = "February";
break;
default:
month = "Month not found";
break;
}
// Return the value to pass to the target.
return month;
}
// ConvertBack is not implemented for a OneWay binding.
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException();
}
}
Bağlama nesne işaretlemenizde bu değer dönüştürücüsünüzü şu şekilde tüketirsiniz.
<UserControl.Resources>
<local:DateToStringConverter x:Key="Converter1"/>
</UserControl.Resources>
...
<TextBlock Grid.Column="0"
Text="{x:Bind ViewModel.Month, Converter={StaticResource Converter1}}"/>
<TextBlock Grid.Column="0"
Text="{Binding Month, Converter={StaticResource Converter1}}"/>
Bağlama için Converter parametresi tanımlanmışsa bağlama altyapısı Convert ve ConvertBack yöntemlerini çağırır. Kaynaktan veri geçirildiğinde bağlama altyapısı çağrılar Convert ve döndürülen verileri hedefe geçirir. Veriler hedeften geçirildiğinde (iki yönlü bağlama için), bağlama altyapısı çağrılır ConvertBack ve döndürülen verileri kaynağa geçirir.
Dönüştürücü ayrıca isteğe bağlı parametrelere de sahiptir: Dönüştürmede kullanılacak dilin belirtilmesine olanak tanıyan ConverterLanguage ve dönüştürme mantığı için bir parametrenin geçirilmesine olanak tanıyan ConverterParameter. Dönüştürücü parametresi kullanan bir örnek için bkz. IValueConverter.
Uyarı
Dönüştürmede bir hata varsa, özel durum oluşturma. Bunun yerine, veri aktarımını durduracak DependencyProperty.UnsetValue değerini döndürebilirsiniz.
Bağlama kaynağı çözümlenemediğinde kullanılacak varsayılan değeri görüntülemek için, işaretlemedeki bağlama nesnesinde özelliğini ayarlayın FallbackValue . Bu, dönüştürme ve biçimlendirme hatalarını işlemek için yararlıdır. Ayrıca, heterojen türlerden oluşan ilişkili bir koleksiyondaki tüm nesnelerde varolmayabilecek kaynak özelliklere bağlanmak da yararlıdır.
Metin denetimini dize olmayan bir değere bağlarsanız, veri bağlama altyapısı değeri dizeye dönüştürür. Değer bir başvuru türüyse, veri bağlama altyapısı ICustomPropertyProvider.GetStringRepresentation veya varsa IStringable.ToString çağrısı yaparak dize değerini alır ve aksi takdirde Object.ToString'i çağırır. Ancak, bağlama altyapısının temel sınıf uygulamasını gizleyen tüm ToString uygulamaları yoksayacağını unutmayın. Alt sınıf uygulamaları bunun yerine temel sınıf ToString yöntemini geçersiz kılmalıdır. Benzer şekilde, yerel dillerde tüm yönetilen nesneler ICustomPropertyProvider ve IStringable'ı uyguluyor gibi görünür. Ancak, tüm çağrıları GetStringRepresentation ve IStringable.ToString için yönlendirilir Object.ToString veya bu yöntemi geçersiz kılma, ve hiçbir zaman temel sınıf uygulamasını gizleyen yeni ToString bir uygulamaya.
Uyarı
Windows Topluluk Araç Seti bir BoolToVisibilityConverter sağlar. Dönüştürücü, bir dönüştürücü oluşturmadan bir true özelliği boole değerine bağlayabilmeniz için sabit listesi değerine ve Visiblefalse değerine eşler CollapsedVisibility. Dönüştürücünün kullanılabilmesi için projenizin CommunityToolkit.WinUI.Converters NuGet paketini eklemesi gerekir.
{x:Bind} içinde işlev bağlaması
{x:Bind} bağlama yolundaki son adımın işlev olmasını sağlar. Dönüştürmeleri gerçekleştirmek veya birden fazla özelliğe bağlı bağlamalar oluşturmak için bu özelliği kullanın. Daha fazla bilgi için bkz. x:Bind'deki işlevler.
Öğeden öğeye bağlama
Bir XAML öğesinin özelliğini başka bir XAML öğesinin özelliğine bağlayabilirsiniz. Burada, bu bağlamanın işaretlemede nasıl göründüğüne dair bir örnek verilmiş.
<TextBox x:Name="myTextBox" />
<TextBlock Text="{x:Bind myTextBox.Text, Mode=OneWay}" />
{x:Bind} ile kaynak sözlükleri
{x:Bind} işaretleme uzantısı kod oluşturma işlemine bağlıdır, bu nedenle çağıran InitializeComponent bir oluşturucu içeren arka planda kod dosyası gerekir (oluşturulan kodu başlatmak için). Kaynak sözlüğünü yeniden kullanmak için, dosya adına başvurmak yerine türünü oluşturun, böylece InitializeComponent çağrılır. Burada, var olan bir kaynak sözlüğüne sahipseniz ve bu sözlükte kullanmak {x:Bind} istiyorsanız yapmanız gerekenlere bir örnek verilmiştir.
<!-- TemplatesResourceDictionary.xaml -->
<ResourceDictionary
x:Class="ExampleNamespace.TemplatesResourceDictionary"
.....
xmlns:examplenamespace="using:ExampleNamespace">
<DataTemplate x:Key="EmployeeTemplate" x:DataType="examplenamespace:IEmployee">
<Grid>
<TextBlock Text="{x:Bind Name}"/>
</Grid>
</DataTemplate>
</ResourceDictionary>
// TemplatesResourceDictionary.xaml.cs
using Microsoft.UI.Xaml.Data;
namespace ExampleNamespace
{
public partial class TemplatesResourceDictionary
{
public TemplatesResourceDictionary()
{
InitializeComponent();
}
}
}
<!-- MainWindow.xaml -->
<Window x:Class="ExampleNamespace.MainWindow"
....
xmlns:examplenamespace="using:ExampleNamespace">
<Window.Resources>
<ResourceDictionary>
....
<ResourceDictionary.MergedDictionaries>
<examplenamespace:TemplatesResourceDictionary/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
</Window>
{x:Bind} ve {Binding} yeniden kullanılabilir bir Stilde karıştırılır
Önceki örnekte DataTemplates'te nasıl kullanılacağı {x:Bind} gösterildi. Ayrıca, hem {x:Bind} hem de {Binding} işaretleme uzantılarını birleştiren yeniden kullanılabilir Stiller oluşturabilirsiniz. Bu birleşim, bazı özellikleri {x:Bind} kullanarak derleme zamanı bilinen değerlerine bağlamak ve diğer özellikleri {Binding} kullanarak çalışma zamanı DataContext değerlerine bağlamak istediğinizde kullanışlıdır.
Aşağıdaki örnekte, her iki bağlama yaklaşımını da kullanan yeniden kullanılabilir bir Düğme stilinin nasıl oluşturulacağı gösterilmektedir:
TemplatesResourceDictionary.xaml
<!-- TemplatesResourceDictionary.xaml -->
<ResourceDictionary
x:Class="ExampleNamespace.TemplatesResourceDictionary"
.....
xmlns:examplenamespace="using:ExampleNamespace">
<!-- DataTemplate using x:Bind -->
<DataTemplate x:Key="EmployeeTemplate" x:DataType="examplenamespace:IEmployee">
<Grid>
<TextBlock Text="{x:Bind Name}"/>
</Grid>
</DataTemplate>
<!-- Style that mixes x:Bind and Binding -->
<Style x:Key="CustomButtonStyle" TargetType="Button">
<Setter Property="Background" Value="{Binding ButtonBackgroundBrush}"/>
<Setter Property="Foreground" Value="{Binding ButtonForegroundBrush}"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="RootBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<!-- x:Bind to a static property or page-level property -->
<Ellipse Width="8" Height="8"
Fill="{x:Bind DefaultIndicatorBrush}"
Margin="0,0,8,0"/>
<!-- Binding to DataContext -->
<ContentPresenter x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}"/>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<!-- Binding to DataContext for hover color -->
<Setter Target="RootBorder.Background"
Value="{Binding ButtonHoverBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<!-- x:Bind to a compile-time known resource -->
<Setter Target="RootBorder.Background"
Value="{x:Bind DefaultPressedBrush}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
TemplatesResourceDictionary.xaml.cs
// TemplatesResourceDictionary.xaml.cs
using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media;
namespace ExampleNamespace
{
public partial class TemplatesResourceDictionary
{
public TemplatesResourceDictionary()
{
InitializeComponent();
}
// Properties for x:Bind - these are compile-time bound
public SolidColorBrush DefaultIndicatorBrush { get; } =
new SolidColorBrush(Colors.Green);
public SolidColorBrush DefaultPressedBrush { get; } =
new SolidColorBrush(Colors.DarkGray);
}
}
Çalışma zamanı değerleri sağlayan bir ViewModel ile MainWindow.xaml'de kullanım:
<!-- MainWindow.xaml -->
<Window x:Class="ExampleNamespace.MainWindow"
....
xmlns:examplenamespace="using:ExampleNamespace">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<examplenamespace:TemplatesResourceDictionary/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.DataContext>
<examplenamespace:ButtonThemeViewModel/>
</Grid.DataContext>
<StackPanel Margin="20">
<!-- These buttons use the mixed binding style -->
<Button Content="Save" Style="{StaticResource CustomButtonStyle}"/>
<Button Content="Cancel" Style="{StaticResource CustomButtonStyle}"/>
</StackPanel>
</Grid>
</Window>
ButtonThemeViewModel.cs (çalışma zamanı bağlama değerleri sağlayan DataContext):
using System.ComponentModel;
using Microsoft.UI;
using Microsoft.UI.Xaml.Media;
namespace ExampleNamespace
{
public class ButtonThemeViewModel : INotifyPropertyChanged
{
private SolidColorBrush _buttonBackgroundBrush = new SolidColorBrush(Colors.LightBlue);
private SolidColorBrush _buttonForegroundBrush = new SolidColorBrush(Colors.DarkBlue);
private SolidColorBrush _buttonHoverBrush = new SolidColorBrush(Colors.LightCyan);
public SolidColorBrush ButtonBackgroundBrush
{
get => _buttonBackgroundBrush;
set
{
_buttonBackgroundBrush = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonBackgroundBrush)));
}
}
public SolidColorBrush ButtonForegroundBrush
{
get => _buttonForegroundBrush;
set
{
_buttonForegroundBrush = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonForegroundBrush)));
}
}
public SolidColorBrush ButtonHoverBrush
{
get => _buttonHoverBrush;
set
{
_buttonHoverBrush = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonHoverBrush)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
Bu örnekte:
-
{Binding}DataContext'e bağlı özellikler için kullanılır (ButtonBackgroundBrush, ButtonForegroundBrush, ButtonHoverBrush) -
{x:Bind}bilinen ve ResourceDictionary'nin kendisine ait olan derleme zamanı özellikleri için kullanılır (DefaultIndicatorBrush, DefaultPressedBrush) - Stil yeniden kullanılabilir ve herhangi bir Düğmeye uygulayabilirsiniz
- Çalışma zamanı temalı, statik öğeler için performansından
{x:Bind}yararlanmaya devam ederken DataContext aracılığıyla mümkündür
Olay bağlama ve ICommand
{x:Bind} , olay bağlama adlı bir özelliği destekler. Bu özellik sayesinde bağlama kullanarak bir olayın işleyicisini belirtebilirsiniz. Bu özellik, arka planda kod dosyasındaki bir yöntemle olayları işlemenin yanı sıra olayları işlemek için ek bir seçenektir. Sınıfınızda bir ListViewDoubleTapped olay işleyicisi MainWindow olduğunu varsayalım.
public sealed partial class MainWindow : Window
{
...
public void ListViewDoubleTapped()
{
// Handle double-tapped logic
}
}
ListView'un DoubleTapped olayını MainWindow'daki bir yönteme şöyle bağlayabilirsiniz.
<ListView DoubleTapped="{x:Bind ListViewDoubleTapped}" />
Bu teknikle bir olayı işlemek için aşırı yüklenmiş yöntemler kullanamazsınız. Ayrıca, olayı işleyen yöntemin parametreleri varsa, bunların tümü sırasıyla tüm olay parametrelerinin türlerinden atanabilir olmalıdır. Bu durumda, ListViewDoubleTapped aşırı yüklenmez ve parametresi yoktur (ancak iki object parametre alsa bile geçerli olacaktır).
Olay bağlama tekniği, komutları uygulama ve kullanma işlemine benzer. Komut, ICommand arabirimini uygulayan bir nesne döndüren bir özelliktir. Hem {x:Bind} hem de {Binding} komutlarla çalışır. Komut düzenini birden çok kez uygulamanız gerekmeyecek şekilde, DelegateCommand UWP örneğinde ("Ortak" klasöründe) bulduğunuz yardımcı sınıfını kullanabilirsiniz.
Klasör veya dosya koleksiyonuna bağlama
Paketlenmiş Windows Uygulama SDK'sı uygulamalarınızdaki klasör ve dosya verilerini almak için Windows.Storage ad alanındaki API'leri kullanabilirsiniz. Ancak, çeşitli GetFilesAsync, GetFoldersAsyncve GetItemsAsync yöntemleri liste denetimlerine bağlamaya uygun değerler döndürmez. Bunun yerine, FileInformationFactory sınıfının GetVirtualizedFilesVector, GetVirtualizedFoldersVector ve GetVirtualizedItemsVector yöntemlerinin dönüş değerlerine bağlamanız gerekir.
StorageDataSource ve GetVirtualizedFilesVector UWP örneğindeki aşağıdaki kod örneği tipik kullanım desenini gösterir. Uygulama paketi bildiriminizde picturesLibrary özelliğini bildirmeyi unutmayın ve Resimler kitaplığı klasörünüzde resimler olduğunu onaylayın.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var library = Windows.Storage.KnownFolders.PicturesLibrary;
var queryOptions = new Windows.Storage.Search.QueryOptions();
queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;
var fileQuery = library.CreateFileQueryWithOptions(queryOptions);
var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
fileQuery,
Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
190,
Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
false
);
var dataSource = fif.GetVirtualizedFilesVector();
this.PicturesListView.ItemsSource = dataSource;
}
Bu yaklaşımı genellikle dosya ve klasör bilgilerinin salt okunur bir görünümünü oluşturmak için kullanırsınız. Dosya ve klasör özelliklerine iki yönlü bağlamalar oluşturabilirsiniz; örneğin, kullanıcıların müzik görünümünde bir şarkıyı derecelendirmesine izin vermek için. Ancak, uygun SavePropertiesAsync yöntemi çağırana kadar değişiklikler kalıcı olmaz (örneğin, MusicProperties.SavePropertiesAsync). Bu eylem bir seçim sıfırlaması tetiklediğinden, öğe odağı kaybettiğinde değişiklikleri işlemeniz gerekir.
Bu tekniği kullanarak iki yönlü bağlamanın yalnızca Müzik gibi dizine alınan konumlarla çalıştığını unutmayın. FolderInformation.GetIndexedStateAsync yöntemini çağırarak bir konumun dizine alınıp alınmadığını belirleyebilirsiniz.
Ayrıca, sanallaştırılmış vektörlerin bazı öğeler için değerlerini doldurmadan önce döndürebileceğini null unutmayın. Örneğin, sanallaştırılmış vektöre bağlı bir liste denetiminin null değerini kullanmadan önce veya bunun yerine SelectedIndex'i kullanmadan önce öğesini denetlemeniz gerekir.
Anahtara göre gruplandırılmış verilere bağlama
Düz bir öğe koleksiyonu (örneğin, bir BookSku sınıf tarafından temsil edilen kitaplar) alırsanız ve ortak bir özelliği anahtar olarak kullanarak öğeleri gruplandırdıysanız ( BookSku.AuthorName örneğin, özellik), sonuç gruplandırılmış veri olarak adlandırılır. Verileri gruplandırdığınızda, bu artık düz bir koleksiyon değildir. Gruplandırılmış veriler, her grup nesnesinin sahip olduğu bir grup nesneleri koleksiyonudur:
- bir anahtar ve
- özelliği bu anahtarla eşleşen öğe koleksiyonu.
Kitaplar örneğini yeniden almak için, kitapları yazar adına göre gruplandırma sonucu, her grubun sahip olduğu bir yazar adı grupları koleksiyonuyla sonuçlanır:
- bir yazar adı olan bir anahtar ve
- özelliği grubun anahtarıyla eşleşen nesnelerin
BookSkukoleksiyonuAuthorName.
Genel olarak, bir koleksiyonu görüntülemek için bir öğe denetiminin ItemsSource'unu (ListView veya GridView gibi) doğrudan koleksiyon döndüren bir özelliğe bağlarsınız. Bu düz bir öğe koleksiyonuysa, özel bir şey yapmanız gerekmez. Ancak grup nesnelerinin bir koleksiyonuysa (gruplandırılmış verilere bağlanırken olduğu gibi), öğe denetimi ile bağlama kaynağı arasında yer alan CollectionViewSource adlı bir ara nesnenin hizmetlerine ihtiyacınız vardır. öğesini gruplandırılmış verileri döndüren özelliğe bağlarsınız CollectionViewSource ve öğe denetimini öğesine CollectionViewSourcebağlarsınız. değerinin ek bir değer eklemesi CollectionViewSource , geçerli öğeyi izlemesi ve böylece birden fazla öğe denetimini eşitlenmiş durumda tutmak için tümünü aynı CollectionViewSourceöğesine bağlamanızdır. Geçerli öğeye, CollectionViewSource.View özelliği tarafından döndürülen nesnenin ICollectionView.CurrentItem özelliği aracılığıyla program aracılığıyla da erişebilirsiniz.
CollectionViewSource'un gruplandırma tesisini etkinleştirmek için IsSourceGrouped değerini olarak trueayarlayın.
ItemsPath özelliğini de ayarlamanız gerekip gerekmediği, grup nesnelerinizi tam olarak nasıl yazdığınıza bağlıdır. Grup nesnesi yazmanın iki yolu vardır: "is-a-group" deseni ve "has-a-group" deseni. "is-a-group" deseninde, grup nesnesi bir koleksiyon türünden türetilir (örneğin, List<T>), bu nedenle grup nesnesi aslında öğe grubudur. Bu düzende ayarlamanız ItemsPathgerekmez. "Has-a-group" deseninde, grup nesnesinin koleksiyon türünde bir veya daha fazla özelliği (gibi List<T>) vardır, bu nedenle grubun bir özellik biçiminde bir öğe grubu (veya birkaç özellik biçiminde birkaç öğe grubu) vardır. Bu desenle, öğe grubunu içeren özelliğin adına ayarlamanız ItemsPath gerekir.
Aşağıdaki örnekte "has-a-group" deseni gösterilmektedir. Pencere sınıfı, görünüm modelimizin bir örneğini döndüren DataContext adlı bir özelliğe sahiptir.
CollectionViewSource, görünüm modelinin Authors özelliğine bağlanır (Authorsgrup nesnelerinin koleksiyonudur) ve gruplandırılmış öğeleri içeren özelliğin bu olduğunu belirtirAuthor.BookSkus. Son olarak , GridView öğesine bağlıdır CollectionViewSourceve öğeleri gruplar halinde işleyebilmesi için grup stili tanımlanmıştır.
<Window.Resources>
<CollectionViewSource
x:Name="AuthorHasACollectionOfBookSku"
Source="{x:Bind ViewModel.Authors}"
IsSourceGrouped="true"
ItemsPath="BookSkus"/>
</Window.Resources>
...
<GridView
ItemsSource="{x:Bind AuthorHasACollectionOfBookSku}" ...>
<GridView.GroupStyle>
<GroupStyle
HeaderTemplate="{StaticResource AuthorGroupHeaderTemplateWide}" ... />
</GridView.GroupStyle>
</GridView>
"Grupdur" desenini iki yoldan biriyle uygulayabilirsiniz. Bunun bir yolu kendi grup sınıfınızı yazmaktır. sınıfından List<T> türet ( burada T , öğelerin türüdür). Örneğin, public class Author : List<BookSku>. İkinci yol, BookSku öğelerinin özellik değerleri gibi grup nesnelerini (ve grup sınıfını) dinamik olarak oluşturmak için LINQ ifadesi kullanmaktır. Öğelerin yalnızca düz bir listesini korumak ve bunları anında gruplandırma yaklaşımı, bulut hizmetinden verilere erişen bir uygulamaya özgüdür.
Yazar ve Tarz gibi özel grup sınıflarına gerek kalmadan kitapları yazara veya tarza göre (örneğin) gruplandırma esnekliğine sahip olursunuz.
Aşağıdaki örnekte LINQ kullanan "is-a-group" deseni gösterilmektedir. Bu kez kitapları, grup üst bilgilerinde tarz adıyla görüntülenen türe göre gruplandırıyoruz. Bu gruplandırma, grup Anahtarı değerine başvuruda " Anahtar " özellik yolu ile gösterilir.
using System.Linq;
...
private IOrderedEnumerable<IGrouping<string, BookSku>> genres;
public IOrderedEnumerable<IGrouping<string, BookSku>> Genres
{
get
{
if (genres == null)
{
genres = from book in bookSkus
group book by book.genre into grp
orderby grp.Key
select grp;
}
return genres;
}
}
Veri şablonlarıyla {x:Bind} kullanırken, bir x:DataType değer ayarlayarak bağlanılan türü belirtmeniz gerektiğini unutmayın. Tür genelse, bunu işaretlemede ifade edemediğiniz için grup stili üst bilgi şablonunda bunun yerine {Binding} kullanmanız gerekir.
<Grid.Resources>
<CollectionViewSource x:Name="GenreIsACollectionOfBookSku"
Source="{x:Bind Genres}"
IsSourceGrouped="true"/>
</Grid.Resources>
<GridView ItemsSource="{x:Bind GenreIsACollectionOfBookSku}">
<GridView.ItemTemplate x:DataType="local:BookTemplate">
<DataTemplate>
<TextBlock Text="{x:Bind Title}"/>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
SemanticZoom denetimi, kullanıcılarınızın gruplandırılmış verileri görüntülemesi ve bu verilerde gezinmesi için harika bir yoldur.
Bookstore2 UWP örnek uygulaması, uygulamasının SemanticZoomnasıl kullanılacağını gösterir. Bu uygulamada, yazara göre gruplandırılmış kitapların listesini (yakınlaştırılmış görünüm) görüntüleyebilir veya yazarların atlama listesini (uzaklaştırılmış görünüm) görmek için uzaklaştırabilirsiniz. Atlama listesi, kitap listesinde gezinmekten çok daha hızlı gezinmeyi sağlar. Yakınlaştırılan ve uzaklaştırılan görünümler aslında ListView veya GridView denetimleri aynı CollectionViewSourceile ilişkilidir.
Hiyerarşik verilere (kategoriler içindeki alt kategoriler gibi) bağlandığınızda, kullanıcı arabiriminizdeki hiyerarşik düzeyleri bir dizi öğe denetimiyle görüntülemeyi seçebilirsiniz. Bir öğe denetimindeki seçim, sonraki öğe denetimlerinin içeriğini belirler. Her listeyi kendi CollectionViewSource'a bağlayarak ve örnekleri zincirde birbirine bağlayarak CollectionViewSource listeleri eşitlenmiş olarak tutabilirsiniz. Bu kurulum ana/ayrıntılar (veya liste/ayrıntılar) görünümü olarak adlandırılır. Daha fazla bilgi için bkz. Hiyerarşik verilere bağlanma ve ana/ayrıntılar görünümü oluşturma.
Veri bağlama sorunlarını tanılama ve hata ayıklama
Bağlama işaretlemeniz özelliklerin adlarını (ve C# için bazen alanlar ve yöntemler) içerir. Bu nedenle, bir özelliği yeniden adlandırdığınızda, buna başvuran bağlamaları da değiştirmeniz gerekir. Bunu yapmayı unutursanız bir veri bağlama hatası oluşturursunuz ve uygulamanız derlenmiyor veya düzgün çalışmıyor.
{x:Bind} ve {Binding} tarafından oluşturulan bağlama nesneleri büyük ölçüde işlevsel olarak eşdeğerdir. Ancak {x:Bind} bağlama kaynağı için tür bilgilerine sahiptir ve derleme zamanında kaynak kodu oluşturur. ile {x:Bind}, kodunuzun geri kalanıyla elde ettiğiniz sorun algılama türünü elde edersiniz. Bu algılama, bağlama ifadelerinizin derleme zamanı doğrulamasını ve sayfanızın kısmi sınıfı olarak oluşturulan kaynak kodda kesme noktaları ayarlayarak hata ayıklamayı içerir. Bu sınıfları klasörünüzdeki obj dosyalarda (C#için) <view name>.g.csgibi adlarla bulabilirsiniz. Bağlamayla ilgili bir sorun varsa, Microsoft Visual Studio hata ayıklayıcısında İşlenmeyen Özel Durumlarda Kesme özelliğini açın. Hata ayıklayıcı bu noktada yürütmeyi keser ve ardından neyin yanlış gittiğinin hatalarını ayıklayabilirsiniz. tarafından {x:Bind} oluşturulan kod, bağlama kaynak düğümlerinin grafiğinin her parçası için aynı deseni izler ve soruna yol açan çağrıların sırasını saptamaya yardımcı olması için Çağrı Yığını penceresindeki bilgileri kullanabilirsiniz.
{Binding} bağlama kaynağı için tür bilgilerine sahip değil. Ancak uygulamanızı hata ayıklayıcı ekli olarak çalıştırdığınızda, Visual Studio'daki Çıkış ve XAML Bağlama Hataları pencerelerinde bağlama hataları görüntülenir. Visual Studio'da bağlama hatalarını ayıklama hakkında daha fazla bilgi için bkz . XAML veri bağlama tanılamaları.
Kodda bağlama oluşturma
Uyarı
Kodda {x:Bind} bağlamaları oluşturamadığınız için bu bölüm yalnızca {Binding} için geçerlidir. Ancak, bağımlılık özelliklerinde değişiklik bildirimlerine kaydolmanızı sağlayan {x:Bind} ile aynı avantajlardan bazılarını elde edebilirsiniz.
Ayrıca XAML yerine yordam kodu kullanarak ui öğelerini verilere bağlayabilirsiniz. Bunu yapmak için yeni bir Binding nesnesi oluşturun, uygun özellikleri ayarlayın, ardından FrameworkElement.SetBinding veya BindingOperations.SetBinding öğesini çağırın. Bağlamaları program aracılığıyla oluşturmak, çalışma zamanında bağlama özelliği değerlerini seçmek veya birden çok denetim arasında tek bir bağlama paylaşmak istediğinizde yararlıdır. Ancak, çağrısından SetBindingsonra bağlama özelliği değerlerini değiştiremezsiniz.
Aşağıdaki örnekte kodda bağlamanın nasıl uygulanacakları gösterilmektedir.
<TextBox x:Name="MyTextBox" Text="Text"/>
// Create an instance of the MyColors class
// that implements INotifyPropertyChanged.
var textcolor = new MyColors();
// Brush1 is set to be a SolidColorBrush with the value Red.
textcolor.Brush1 = new SolidColorBrush(Colors.Red);
// Set the DataContext of the TextBox MyTextBox.
MyTextBox.DataContext = textcolor;
// Create the binding and associate it with the text box.
var binding = new Binding { Path = new PropertyPath("Brush1") };
MyTextBox.SetBinding(TextBox.ForegroundProperty, binding);
{x:Bind} ve {Binding} özellik karşılaştırması
| Özellik | {x:Bind} ile {Binding} karşılaştırması | Notes |
|---|---|---|
| Yol varsayılan özelliktir | {x:Bind a.b.c}- {Binding a.b.c} |
|
| Path özelliği | {x:Bind Path=a.b.c}- {Binding Path=a.b.c} |
x:Bind içindePath, datacontext değil varsayılan olarak Window'da kök olarak oluşturulur. |
| Indexer | {x:Bind Groups[2].Title}- {Binding Groups[2].Title} |
Koleksiyonda belirtilen öğeye bağlar. Yalnızca tamsayı tabanlı dizinler desteklenir. |
| Ekli özellikler | {x:Bind Button22.(Grid.Row)}- {Binding Button22.(Grid.Row)} |
Eklenen özellikler parantezler kullanılarak belirtilir. Özellik bir XAML namespace'inde bildirilmemişse, belgenin başındaki bir kod namespace'ine eşlenmesi gereken bir XML namespace'ini önek olarak ekleyin. |
| Döküm | {x:Bind groups[0].(data:SampleDataGroup.Title)}- için {Binding}gerekli değildir. |
Atamalar parantezler kullanılarak belirtilir. Özellik bir XAML ad alanında bildirilmemişse, belgenin başına bir kod ad alanıyla eşlenmesi gereken bir XML ad alanı ile ön getirin. |
| Dönüştürücü | {x:Bind IsShown, Converter={StaticResource BoolToVisibility}}- {Binding IsShown, Converter={StaticResource BoolToVisibility}} |
Window, Control, ResourceDictionary veya App.xaml'in kökünde dönüştürücüleri bildirin. |
| ConverterParameter, ConverterLanguage | {x:Bind IsShown, Converter={StaticResource BoolToVisibility}, ConverterParameter=One, ConverterLanguage=fr-fr}- {Binding IsShown, Converter={StaticResource BoolToVisibility}, ConverterParameter=One, ConverterLanguage=fr-fr} |
Window, Control, ResourceDictionary veya App.xaml'in kökünde dönüştürücüleri bildirin. |
| TargetNullValue | {x:Bind Name, TargetNullValue=0}- {Binding Name, TargetNullValue=0} |
Bağlama ifadesinin yaprağı null olduğunda kullanılır. Dize değeri için tek tırnak işareti kullanın. |
| FallbackValue | {x:Bind Name, FallbackValue='empty'}- {Binding Name, FallbackValue='empty'} |
Bağlama yolunun herhangi bir bölümü (yaprak hariç) null olduğunda kullanılır. |
| ÖğeAdı | {x:Bind slider1.Value}- {Binding Value, ElementName=slider1} |
Bir {x:Bind} alana bağlandığınızda, Path varsayılan olarak Window'da kök olarak oluşturulur, böylece adlandırılmış herhangi bir öğeye alanı üzerinden erişebilirsiniz. |
| RelativeSource: Self | <Rectangle x:Name="rect1" Width="200" Height="{x:Bind rect1.Width}" ... />- <Rectangle Width="200" Height="{Binding Width, RelativeSource={RelativeSource Self}}" ... /> |
ile {x:Bind}öğesini adlandırın ve öğesinin adını içinde Pathkullanın. |
| RelativeSource: ŞablonlanmışÜstElemant | Için gerekli değil {x:Bind}- {Binding <path>, RelativeSource={RelativeSource TemplatedParent}} |
ile{x:Bind}, açık TargetType olarakControlTemplate, şablon üst öğesine bağlamayı gösterir. için {Binding}, çoğu kullanım için denetim şablonlarında normal şablon bağlama kullanılabilir. Ancak dönüştürücü veya iki yönlü bağlama kullanmanız gereken yerde kullanın TemplatedParent . |
| Kaynak | Için gerekli değil {x:Bind}- <ListView ItemsSource="{Binding Orders, Source={StaticResource MyData}}"/> |
{x:Bind} için adlandırılmış öğeyi doğrudan kullanabilir, bir özellik kullanabilir veya statik bir yol belirtebilirsiniz. |
| Mode | {x:Bind Name, Mode=OneWay}- {Binding Name, Mode=TwoWay} |
Mode, OneTimeveya OneWayolabilirTwoWay.
{x:Bind}varsayılan olarak; OneTime{Binding} varsayılan değeridirOneWay. |
| UpdateSourceTrigger | {x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}- {Binding UpdateSourceTrigger=PropertyChanged} |
UpdateSourceTrigger, Defaultveya LostFocusolabilirPropertyChanged.
{x:Bind} desteklemez UpdateSourceTrigger=Explicit.
{x:Bind}, dışında PropertyChangeddavranış kullandığı tüm durumlar için davranışı kullanır.TextBox.TextLostFocus |
Ayrıca bakınız
Windows developer