2012-07-11 64 views
31

Desde un control personalizado basado en TextBox, creé una propiedad denominada Items, de esta manera:Un 'vinculante' sólo se puede establecer en un DependencyProperty de DependencyObject

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

Cuando se utiliza el control personalizado en XAML , No puedo vincular la propiedad porque genera una excepción "A 'Binding' solo se puede establecer en DependencyProperty de DependencyObject".

¿Cómo resuelvo esta excepción?

+2

Sí.Solo las propiedades de Dependencia pueden actuar como objetivos para enlaces. La fuente podría ser una propiedad de dependencia o una propiedad CLR que implementa INotifyPropertyChanged – Gishu

+0

Este es un duplicado exacto de su otra pregunta, donde acepta una respuesta y dice "pero tuve que modificar la propiedad para incluir DependencyProperty". Su solución debería haberse incluido como respuesta allí – arserbin3

+5

@AdamHouldsworth Sí, esta pregunta se publicó solo para publicar la respuesta. Esto se fomenta realmente ya que se lo considera una forma de compartir conocimiento, e incluso hay un [nuevo 'CheckBox' en el formulario Ask Question] (http://meta.stackexchange.com/questions/132886/what-is- this-answer-your-own-question-jazz) que te permitirá escribir una respuesta al mismo tiempo que escribes tu pregunta. – Rachel

Respuesta

20

Para resolver esta excepción, debe cambiar la propiedad Items y agregar DependencyProperty que funcionará como un "enlace" en XAML. La clase será:

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

Como nota al margen, es también digno de mención que obtendrá estos errores vinculantes si copia y pegar entre objetos y olvidarse de cambiar la segunda declaración typeof(Object).

No pude averiguar durante una buena hora por qué estaba recibiendo este error ya que todo parecía estar definido y correcto. Había movido mis propiedades a un control de usuario porque quería pasar de un único conjunto a una lista. Por lo tanto:

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

habríamos llegado a ser:

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

hasta que hice este cambio me quedé recibir el 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.

+3

Esto. Copié un UserControl con algunas DependencyProperties y eso significa que el antiguo '' typeof (____) '' -Value todavía existe y es válido. No obtengo ningún error hasta el tiempo de ejecución. Y luego XAML Parsing Exception "Un enlace solo se puede configurar ..." y así sucesivamente. ¡Gracias! – ecth

+0

Puede existir, pero salpique los tipos propuestos que realmente coinciden. – netniV

+0

No, ese es el punto. Quise decir que la clase existe y es válida. Por lo tanto, no obtendrá ningún error en VS. Hasta que compiles y corras. ¡Pero entonces no sabes de dónde viene el error! Esa fue mi mistyke después de copiar .. – ecth

3

Otra posible causa de esto es cuando se proporciona un mal tipo para el valor predeterminado en los metadatos.
Por ejemplo:

new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged) 

lanzaría este error si escribió en su lugar:

new PropertyMetadata(false, OnItemsPropertyChanged) 

Esto también puede suceder si va a copiar y pegar desde una fuente de código.

16

Aquí hay otro problema: asegúrese de que la cadena en el primer argumento de DependencyProperty.Register() concuerde con el nombre de la propiedad relacionada.

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

Me encontré con este problema cuando cambié el nombre de mi propiedad sin cambiar la cadena.

+4

Asegúrese de que el nombre sea "Artículos", no "Propiedad de artículos" –

+7

Puede usar el nombre de (Elementos) en versiones .NET recientes para evitar este problema. – Herman

0

tuve el mensaje (+ tiempo de ejecución designtime):

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.

Cuando yo era lo suficientemente inteligente como para definir un disparador en una propiedad VM ..

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

Cuál debería por supuesto ser un DataTrigger (que utiliza Encuadernación en lugar de Propiedad)

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

Los disparadores son típicamente para Control (Botón, TextBox , FrameworkElement etc.) propiedades.

Cuestiones relacionadas