web-dev-qa-db-fra.com

Une «liaison» ne peut être définie que sur une propriété de dépendance d'un objet de dépendance

À partir d'un contrôle personnalisé basé sur TextBox, j'ai créé une propriété nommée Items, de cette manière:

public class NewTextBox : TextBox
{
    public ItemCollection Items { get; set; }
}

Lorsque j'utilise le contrôle personnalisé dans XAML, je ne peux pas lier la propriété car elle déclenche l'exception "Une 'liaison' ne peut être définie que sur une DependencyProperty d'un DependencyObject.".

Comment résoudre cette exception?

45
mgottschild

En remarque, il convient également de noter que vous obtiendrez ces erreurs de liaison si vous copiez et collez entre les objets et oubliez de modifier la deuxième instruction typeof(Object).

Je n'ai pas pu comprendre pendant une bonne heure pourquoi j'obtenais cette erreur car tout semblait être défini et correct. J'avais déplacé mes propriétés dans un contrôle utilisateur car je voulais passer d'un ensemble unique à une liste. Ainsi:

public static readonly DependencyProperty FoldersProperty = DependencyProperty.Register("Folders", typeof(OutlookFolders), typeof(MainWindow), new FrameworkPropertyMetadata(new OutlookFolders()));

public OutlookFolders Folders
{
    get { return GetValue(FoldersProperty) as OutlookFolders; }
    set { SetValue(FoldersProperty, value); }
}

Devrait être devenu:

public static readonly DependencyProperty FoldersProperty = DependencyProperty.Register("Folders", typeof(OutlookFolders), typeof(SavedFolderControl), new FrameworkPropertyMetadata(new OutlookFolders()));

public OutlookFolders Folders
{
    get { return GetValue(FoldersProperty) as OutlookFolders; }
    set { SetValue(FoldersProperty, value); }
}

Jusqu'à ce que j'effectue ce changement, je continuais à recevoir l'erreur: A 'Binding' cannot be set on the property 'Folders' of type 'SavedFolderControl'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

76
netniV

Pour résoudre cette exception, vous devez modifier la propriété Items et ajouter un DependencyProperty qui fonctionnera comme un "lien" en XAML. La classe sera:

public class AutocompleteTextBox : TextBox
{
    public ItemCollection Items
    {
        get {
            return (ItemCollection)GetValue(ItemsProperty); }
        set {
            SetValue(ItemsProperty, value); }
    }

    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register(
            "Items",
            typeof(ItemCollection),
            typeof(AutocompleteTextBox),
            new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged));

    private static void OnItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // AutocompleteTextBox source = d as AutocompleteTextBox;
        // Do something...
    }
27
mgottschild

Voici un autre problème: assurez-vous que la chaîne dans le premier argument de DependencyProperty.Register() correspond au nom de la propriété associée.

public static readonly DependencyProperty ItemsProperty =
    DependencyProperty.Register(
        "TheItems", // This is wrong
        typeof(ItemCollection),
        typeof(AutocompleteTextBox),
        new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged));

J'ai rencontré ce problème lorsque j'ai renommé ma propriété sans modifier la chaîne.

22
Oliver

Une autre cause potentielle de ceci est lorsque vous fournissez un mauvais type pour la valeur par défaut dans les métadonnées.
Par exemple:

new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged)

jetterait cette erreur si vous écriviez à la place:

new PropertyMetadata(false, OnItemsPropertyChanged)

Cela peut également se produire si vous copiez et collez à partir d'une source de code.

3

J'ai eu le message (runtime + designtime):

Une exception non gérée de type "System.Windows.Markup.XamlParseException" s'est produite dans PresentationFramework.dll

Informations supplémentaires: Une "liaison" ne peut pas être définie sur la propriété "propriété" de type "déclencheur". Un "Binding" ne peut être défini que sur une DependencyProperty d'un DependencyObject.

Où j'étais assez intelligent pour définir un déclencheur sur une propriété VM ..

// incorrect.. cannot have Trigger for VM property
<Trigger Property="{Binding IsExpanded}" Value="True">
  <Setter Property="Visibility" Value="Visible"/>
</Trigger>

Qui devrait bien sûr être un déclencheur de données (qui utilise la liaison au lieu de la propriété)

<DataTrigger Binding="{Binding IsExpanded}" Value="True">
  <Setter Property="Visibility" Value="Visible"/>
</DataTrigger>

Les déclencheurs concernent généralement les propriétés du contrôle (Button, TextBox, FrameworkElement, etc.).

1
EricG