„Обвързване“ може да бъде зададено само на DependencyProperty на DependencyObject

От персонализирана контрола, базирана на TextBox, създадох свойство с име Items по следния начин:

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

Когато използвам персонализираната контрола в XAML, не мога да обвържа свойството, защото предизвиква изключение „„Свързване“ може да бъде зададено само на DependencyProperty на DependencyObject.“.

Как да реша това изключение?


person mgottschild    schedule 11.07.2012    source източник
comment
да Само свойствата на зависимостта могат да действат като цели за обвързвания. Източникът може да бъде свойство на зависимост или свойство на CLR, което имплементира INotifyPropertyChanged   -  person Gishu    schedule 11.07.2012
comment
Това е точен дубликат на другия ви въпрос, където приемате отговор и казвате, но трябваше да променя свойството, за да включва DependencyProperty. Вашето решение трябваше да бъде включено като отговор там   -  person arserbin3    schedule 11.07.2012
comment
@AdamHouldsworth Да, този въпрос беше публикуван само за публикуване на отговора. Това всъщност се насърчава, тъй като се разглежда като форма на споделяне на знания и дори има нов CheckBox във формуляра за задаване на въпрос, който ще ви позволи да напишете отговор едновременно с писането на въпроса си.   -  person Rachel    schedule 11.07.2012
comment
@Рейчъл Честно, не забелязах това, тъй като не съм задавал въпрос от дълго време. Така или иначе, нито съм гласувал против въпроса, нито за отговора, така че ръцете ми са чисти :-)   -  person Adam Houldsworth    schedule 11.07.2012
comment
@arserbin3 Рейчъл има правилното обяснение. И избирам да публикувам тук вместо стария въпрос, тъй като виждам проблема със свързването като различен въпрос от изключението DependencyProperty.   -  person mgottschild    schedule 11.07.2012
comment
@Rachel благодаря за обяснението - аз също не съм виждал това квадратче за отметка преди   -  person arserbin3    schedule 11.07.2012


Отговори (7)


Като странична бележка също така си струва да се отбележи, че ще получите тези грешки при свързване, ако копирате и поставяте между обекти и забравите да промените втория оператор typeof(Object).

Не можех да разбера цял час защо получавам тази грешка, тъй като всичко изглеждаше дефинирано и правилно. Бях преместил свойствата си в потребителски контрол, тъй като исках да премина от единичен набор към списък. По този начин:

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); }
}

Трябваше да стане:

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); }
}

Докато не направих тази промяна, получавах грешката: A 'Binding' cannot be set on the property 'Folders' of type 'SavedFolderControl'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

person netniV    schedule 21.11.2013
comment
Това. Копирах UserControl с някои DependencyProperties и това означава, че старата typeof(____)-стойност все още съществува и е валидна. Не получавам никакви грешки до момента на изпълнение. И тогава XAML Parsing Exception A Binding може да бъде зададен само... и така нататък. Благодаря! - person ecth; 02.08.2016
comment
Може да съществува, но точката предлаганите типове действително съвпадат. - person netniV; 02.08.2016
comment
Не, това е смисълът. Имах предвид, че класът съществува и е валиден. Така че няма да получите никакви грешки във VS. Докато компилирате и стартирате. Но тогава не знаете откъде идва грешката! Това беше моята грешка след копирането.. - person ecth; 02.08.2016
comment
А, да. Това направих и аз. Само пинг в главата ми, когато четох за копиране и поставяне, за да го проверя старателно, тъй като това беше, което бях направил. - person netniV; 02.08.2016
comment
Благодаря, смятам, че ми спестихте около час! - person Avrohom Yisroel; 07.03.2019

За да разрешите това изключение, трябва да промените свойството Items и да добавите DependencyProperty, което ще работи като "връзка" в XAML. Класът ще бъде:

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...
    }
person mgottschild    schedule 11.07.2012

Ето още една грешка: Уверете се, че низът в първия аргумент на DependencyProperty.Register() съвпада с името на свързаното свойство.

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

Сблъсках се с този проблем, когато преименувах собствеността си, без да променя низа.

person Oliver    schedule 12.09.2014
comment
Уверете се, че името е Items, а не ItemsProperty - person Jeson Martajaya; 13.05.2015
comment
Можете да използвате nameof(Items) в последните версии на .NET, за да избегнете този проблем. - person Herman; 18.02.2016

Едно нещо, което забелязах и не съм сигурен, че е споменато някъде, е, че името на вашето DependencyProperty трябва да съвпада с името на вашето свойство

Ако името на вашето свойство е Items, тогава вашето DependencyProperty трябва да бъде ItemsProperty

В моя случай, веднага щом ги съпоставих, грешката изчезна

person Pic Mickael    schedule 03.01.2020
comment
Еха. Не мога да повярвам, че това поправи предупреждението. Няма абсолютно никакъв смисъл, но работи. Въпреки факта, че обвързванията ми работеха по време на изпълнение, продължавах да виждам това предупреждение, докато не промених името на променливата си DependencyProperty с добавено Property. - person WSC; 29.10.2020

Друга потенциална причина за това е, когато предоставите лош тип за стойността по подразбиране в метаданните.
Например:

new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged)

ще предизвика тази грешка, ако вместо това напишете:

new PropertyMetadata(false, OnItemsPropertyChanged)

Това може да се случи и ако копирате и поставяте от източник на код.

person Prof Von Lemongargle    schedule 14.07.2014

Имах съобщението (време на изпълнение + време на проектиране):

Възникна необработено изключение от тип „System.Windows.Markup.XamlParseException“ в PresentationFramework.dll

Допълнителна информация: „Обвързване“ не може да бъде зададено на свойството „Свойство“ от тип „Trigger“. „Обвързване“ може да бъде зададено само на DependencyProperty на DependencyObject.

Когато бях достатъчно умен, за да дефинирам тригер на VM свойство..

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

Което разбира се трябва да бъде тригер за данни (който използва Binding вместо Property)

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

Тригерите обикновено са за свойства на контроли (бутон, текстово поле, FrameworkElement и т.н.).

person EricG    schedule 28.11.2017

Имах този проблем поради липса на надзор от моя страна. написах

<Button.Visibility>
   <MultiBinding Converter="{StaticResource mvbConverter}">
     <Binding Path="{Binding isActive}" />
     <Binding Path="{Binding isCashTransaction}" />
   </MultiBinding>
</Button.Visibility>

когато вместо това трябваше да пиша

<Button.Visibility>
   <MultiBinding Converter="{StaticResource mvbConverter}">
     <Binding Path="isActive" />
     <Binding Path="isCashTransaction" />
   </MultiBinding>
</Button.Visibility>
person RamWill    schedule 01.01.2021