A 'Binding' can only be set on a DependencyProperty of a DependencyObject

做~自己de王妃 提交于 2019-12-28 05:36:18

问题


From a custom control based on TextBox, I created a property named Items, in this way:

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

When using the custom control in XAML, I cannot bind the property because it raises exception "A 'Binding' can only be set on a DependencyProperty of a DependencyObject.".

How do I solve this exception?


回答1:


As a side note, it is also worth noting that you will get these binding errors if you copy and paste between objects and forget to change the second typeof(Object) statement.

I couldn't figure out for a good hour why I was getting this error as everything appeared to be defined and correct. I'd moved my properties into a usercontrol as I wanted to go from a single set to a list. Thus:

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

Should have become:

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

Until I did this change I kept receiving the error: A 'Binding' cannot be set on the property 'Folders' of type 'SavedFolderControl'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.




回答2:


To solve this exception you need to change the property Items and add a DependencyProperty that will work as a "link" in XAML. The class will be:

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...
    }



回答3:


Here's another gotcha: Ensure that the string in the first argument of DependencyProperty.Register() matches the name of the related property.

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

I ran into this issue when I renamed my property without changing the string.




回答4:


Another potential cause of this is when you provide a bad type for the default value in the metadata.
For instance:

new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged)

would throw this error if you wrote instead:

new PropertyMetadata(false, OnItemsPropertyChanged)

This can also happen if you are copying and pasting from a code source.




回答5:


I had the (runtime + designtime) message:

An unhandled exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll

Additional information: A 'Binding' cannot be set on the 'Property' property of type 'Trigger'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

Where I was smart enough to define a Trigger on a VM property..

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

Which should of course be a datatrigger (which uses Binding instead of Property)

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

Triggers are typically for Controls (Button, TextBox, FrameworkElement etc.) properties.



来源:https://stackoverflow.com/questions/11435781/a-binding-can-only-be-set-on-a-dependencyproperty-of-a-dependencyobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!