Koleksiyon türü bağımlılık özellikleri (WPF .NET)
Bu makalede, koleksiyon türü olan bir bağımlılık özelliğini uygulamak için rehberlik ve önerilen desenler sağlanır.
Önemli
.NET 7 ve .NET 6 için Masaüstü Kılavuzu belgeleri yapım aşamasındadır.
Ön koşullar
Makalede bağımlılık özellikleri hakkında temel bilgiler edindiğiniz ve Bağımlılık özelliklerine genel bakış makalesini okuduğunuz varsayılır. Bu makaledeki örnekleri takip etmek için Genişletilebilir Uygulama biçimlendirme dili (XAML) hakkında bilgi sahibi olmanız ve WPF uygulamalarının nasıl yazabileceğinizi bilmeniz yardımcı olur.
Koleksiyon türü bağımlılık özelliği uygulama
Genel olarak, bağımlılık özelliği için uygulama deseni, alan veya başka bir yapı yerine tanımlayıcı DependencyProperty tarafından yedeklenen bir CLR özellik sarmalayıcısıdır. Koleksiyon türü bağımlılık özelliğini uygularken aynı deseni izleyebilirsiniz. Koleksiyon öğesi türü bir veya türetilmiş bir DependencyObjectFreezable sınıfsa desen daha karmaşıktır.
Koleksiyonu başlatma
Bir bağımlılık özelliği oluşturduğunuzda, genellikle ilk özellik değerini belirtmek yerine bağımlılık özelliği meta verileri aracılığıyla varsayılan değeri belirtirsiniz. Ancak, özellik değeriniz bir başvuru türüyse, varsayılan değer bağımlılık özelliğini kaydeden sınıfın oluşturucusunda ayarlanmalıdır. Bağımlılık özelliği meta verileri varsayılan başvuru türü değerini içermemelidir çünkü bu değer sınıfın tüm örneklerine atanır ve tek bir sınıf oluşturulur.
Aşağıdaki örnek, genel List<T>bir Aquarium
içindeki öğe koleksiyonunu FrameworkElement içeren bir sınıf bildirir. Yöntemine RegisterReadOnly(String, Type, Type, PropertyMetadata) geçirilen öğesine varsayılan bir koleksiyon değeri dahil PropertyMetadata değildir ve bunun yerine sınıf oluşturucu, varsayılan koleksiyon değerini yeni bir genel List
olarak ayarlamak için kullanılır.
public class Aquarium : DependencyObject
{
// Register a dependency property with the specified property name,
// property type, owner type, and property metadata.
private static readonly DependencyPropertyKey s_aquariumContentsPropertyKey =
DependencyProperty.RegisterReadOnly(
name: "AquariumContents",
propertyType: typeof(List<FrameworkElement>),
ownerType: typeof(Aquarium),
typeMetadata: new FrameworkPropertyMetadata()
//typeMetadata: new FrameworkPropertyMetadata(new List<FrameworkElement>())
);
// Set the default collection value in a class constructor.
public Aquarium() => SetValue(s_aquariumContentsPropertyKey, new List<FrameworkElement>());
// Declare a public get accessor.
public List<FrameworkElement> AquariumContents =>
(List<FrameworkElement>)GetValue(s_aquariumContentsPropertyKey.DependencyProperty);
}
public class Fish : FrameworkElement { }
Public Class Aquarium
Inherits DependencyObject
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata.
Private Shared ReadOnly s_aquariumContentsPropertyKey As DependencyPropertyKey =
DependencyProperty.RegisterReadOnly(
name:="AquariumContents",
propertyType:=GetType(List(Of FrameworkElement)),
ownerType:=GetType(Aquarium),
typeMetadata:=New FrameworkPropertyMetadata())
'typeMetadata:=New FrameworkPropertyMetadata(New List(Of FrameworkElement)))
' Set the default collection value in a class constructor.
Public Sub New()
SetValue(s_aquariumContentsPropertyKey, New List(Of FrameworkElement)())
End Sub
' Declare a public get accessor.
Public ReadOnly Property AquariumContents As List(Of FrameworkElement)
Get
Return CType(GetValue(s_aquariumContentsPropertyKey.DependencyProperty), List(Of FrameworkElement))
End Get
End Property
End Class
Public Class Fish
Inherits FrameworkElement
End Class
Aşağıdaki test kodu iki ayrı Aquarium
örneğin örneğini oluşturur ve her koleksiyona farklı Fish
bir öğe ekler. Kodu çalıştırırsanız, her Aquarium
örneğin beklendiği gibi tek bir koleksiyon öğesi olduğunu görürsünüz.
private void InitializeAquariums(object sender, RoutedEventArgs e)
{
Aquarium aquarium1 = new();
Aquarium aquarium2 = new();
aquarium1.AquariumContents.Add(new Fish());
aquarium2.AquariumContents.Add(new Fish());
MessageBox.Show(
$"aquarium1 contains {aquarium1.AquariumContents.Count} fish\r\n" +
$"aquarium2 contains {aquarium2.AquariumContents.Count} fish");
}
Private Sub InitializeAquariums(sender As Object, e As RoutedEventArgs)
Dim aquarium1 As New Aquarium()
Dim aquarium2 As New Aquarium()
aquarium1.AquariumContents.Add(New Fish())
aquarium2.AquariumContents.Add(New Fish())
MessageBox.Show($"aquarium1 contains {aquarium1.AquariumContents.Count} fish{Environment.NewLine}" +
$"aquarium2 contains {aquarium2.AquariumContents.Count} fish")
End Sub
Ancak, sınıf oluşturucusunun açıklamalarını çıkarır ve yöntemine RegisterReadOnly(String, Type, Type, PropertyMetadata) varsayılan PropertyMetadata koleksiyon değerini geçirirseniz, her Aquarium
örneğin iki koleksiyon öğesi aldığını görürsünüz! Bunun nedeni, her iki örneğin de Fish
Aquarium sınıfının tüm örnekleri tarafından paylaşılan aynı listeye eklenmesidir. Bu nedenle, amaç her nesne örneğinin kendi listesine sahip olması için olduğunda, varsayılan değer sınıf oluşturucusunda ayarlanmalıdır.
Okuma-yazma koleksiyonunu başlatma
Aşağıdaki örnek, ve anahtar olmayan imza yöntemlerini Register(String, Type, Type)SetValue(DependencyProperty, Object)kullanarak sınıfında okuma-yazma koleksiyon türü bağımlılık özelliğini Aquarium
bildirir.
public class Aquarium : DependencyObject
{
// Register a dependency property with the specified property name,
// property type, and owner type. Store the dependency property
// identifier as a public static readonly member of the class.
public static readonly DependencyProperty AquariumContentsProperty =
DependencyProperty.Register(
name: "AquariumContents",
propertyType: typeof(List<FrameworkElement>),
ownerType: typeof(Aquarium)
);
// Set the default collection value in a class constructor.
public Aquarium() => SetValue(AquariumContentsProperty, new List<FrameworkElement>());
// Declare public get and set accessors.
public List<FrameworkElement> AquariumContents
{
get => (List<FrameworkElement>)GetValue(AquariumContentsProperty);
set => SetValue(AquariumContentsProperty, value);
}
}
Public Class Aquarium
Inherits DependencyObject
' Register a dependency property with the specified property name,
' property type, and owner type. Store the dependency property
' identifier as a static member of the class.
Public Shared ReadOnly AquariumContentsProperty As DependencyProperty =
DependencyProperty.Register(
name:="AquariumContents",
propertyType:=GetType(List(Of FrameworkElement)),
ownerType:=GetType(Aquarium))
' Set the default collection value in a class constructor.
Public Sub New()
SetValue(AquariumContentsProperty, New List(Of FrameworkElement)())
End Sub
' Declare public get and set accessors.
Public Property AquariumContents As List(Of FrameworkElement)
Get
Return CType(GetValue(AquariumContentsProperty), List(Of FrameworkElement))
End Get
Set
SetValue(AquariumContentsProperty, Value)
End Set
End Property
End Class
FreezableCollection bağımlılık özellikleri
Koleksiyon türü bağımlılık özelliği, alt özelliklerindeki değişiklikleri otomatik olarak raporlamaz. Sonuç olarak, bir koleksiyona bağlanıyorsanız, bağlama bazı veri bağlama senaryolarını geçersiz hale getirerek değişiklikleri bildirmeyebilir. Ancak bağımlılık özellik türü için kullanırsanız FreezableCollection<T> , koleksiyon öğelerinin özelliklerindeki değişiklikler düzgün şekilde bildirilir ve bağlama beklendiği gibi çalışır.
Bağımlılık nesneleri koleksiyonunda altözellik bağlamasını etkinleştirmek için, türetilmiş herhangi DependencyObject bir sınıfın tür kısıtlamasıyla koleksiyon türünü FreezableCollection
kullanın.
Aşağıdaki örnek, türü kısıtlaması FrameworkElementolan içeren FreezableCollection
bir sınıf bildirirAquarium
. Yöntemine RegisterReadOnly(String, Type, Type, PropertyMetadata) geçirilen öğesine varsayılan bir koleksiyon değeri dahil PropertyMetadata değildir ve bunun yerine sınıf oluşturucu, varsayılan koleksiyon değerini yeni FreezableCollection
olarak ayarlamak için kullanılır.
public class Aquarium : DependencyObject
{
// Register a dependency property with the specified property name,
// property type, and owner type.
private static readonly DependencyPropertyKey s_aquariumContentsPropertyKey =
DependencyProperty.RegisterReadOnly(
name: "AquariumContents",
propertyType: typeof(FreezableCollection<FrameworkElement>),
ownerType: typeof(Aquarium),
typeMetadata: new FrameworkPropertyMetadata()
);
// Store the dependency property identifier as a static member of the class.
public static readonly DependencyProperty AquariumContentsProperty =
s_aquariumContentsPropertyKey.DependencyProperty;
// Set the default collection value in a class constructor.
public Aquarium() => SetValue(s_aquariumContentsPropertyKey, new FreezableCollection<FrameworkElement>());
// Declare a public get accessor.
public FreezableCollection<FrameworkElement> AquariumContents =>
(FreezableCollection<FrameworkElement>)GetValue(AquariumContentsProperty);
}
Public Class Aquarium
Inherits DependencyObject
' Register a dependency property with the specified property name,
' property type, and owner type.
Private Shared ReadOnly s_aquariumContentsPropertyKey As DependencyPropertyKey =
DependencyProperty.RegisterReadOnly(
name:="AquariumContents",
propertyType:=GetType(FreezableCollection(Of FrameworkElement)),
ownerType:=GetType(Aquarium),
typeMetadata:=New FrameworkPropertyMetadata())
' Set the default collection value in a class constructor.
Public Sub New()
SetValue(s_aquariumContentsPropertyKey, New FreezableCollection(Of FrameworkElement)())
End Sub
' Declare a public get accessor.
Public ReadOnly Property AquariumContents As FreezableCollection(Of FrameworkElement)
Get
Return CType(GetValue(s_aquariumContentsPropertyKey.DependencyProperty), FreezableCollection(Of FrameworkElement))
End Get
End Property
End Class
Ayrıca bkz.
.NET Desktop feedback
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin