'绑定'只能在DependencyObject的DependencyProperty上设置

时间:2012-07-11 15:12:34

标签: c# wpf binding user-controls dependency-properties

在基于TextBox的自定义控件中,我以这种方式创建了一个名为Items的属性:

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

在XAML中使用自定义控件时,我无法绑定属性,因为它引发异常“A'Binding'只能在DependencyObject的DependencyProperty上设置。”。

如何解决此异常?

7 个答案:

答案 0 :(得分:72)

作为旁注,还值得注意的是,如果在对象之间复制和粘贴并忘记更改第二个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.

答案 1 :(得分:25)

要解决此异常,您需要更改属性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...
    }

答案 2 :(得分:19)

这是另一个问题:确保DependencyProperty.Register()的第一个参数中的字符串与相关属性的名称匹配。

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

当我在不更改字符串的情况下重命名我的属性时遇到了这个问题。

答案 3 :(得分:3)

另一个可能的原因是当您为元数据中的默认值提供错误类型时 例如:

new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged)
如果你写的话,

会抛出这个错误:

new PropertyMetadata(false, OnItemsPropertyChanged)

如果从代码源复制和粘贴,也会发生这种情况。

答案 4 :(得分:1)

我有(运行时+设计时)消息:

  

未处理的类型异常   'System.Windows.Markup.XamlParseException'发生在   PresentationFramework.dll

     

附加信息:无法在'Property'上设置'Binding'   “触发器”类型的属性。 '绑定'只能在a上设置   DependencyObject的DependencyProperty。

我足够聪明,可以在VM属性上定义触发器。

// incorrect.. canont 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"/>
</Trigger>

触发器通常用于Control(Button,TextBox,FrameworkElement等)属性。

答案 5 :(得分:1)

我注意到的一件事是,您的DependencyProperty名称必须与您的财产名称相符,但我不确定在任何地方都提到它,

如果您的属性名称为 Items ,则您 DependencyProperty 必须 ItemsProperty

以我为例,只要我与他们匹配,错误就会消失

答案 6 :(得分:0)

我遇到这个问题是因为我缺乏监督。我写了

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