Diferencia entre {Binding PropertyName} y {Binding Path = PropertyName}

He visto ambos estilos usados ​​en el mismo proyecto, y me pregunto si hay alguna diferencia semántica entre ellos, o si alguno sería recomendado sobre el otro y por qué.

No hay ninguno.

Cuando no se especifica, a la propiedad Path se le asigna el valor. En otras palabras, Path es la propiedad predeterminada de un enlace.

Es como la propiedad “Contenido”, que es la propiedad predeterminada para muchos controles. Por ejemplo

Es lo mismo que

Espero que ayude.

Aquí hay una diferencia significativa con la que se encontrará tan pronto como tenga una ruta de propiedad compleja con parámetros escritos.

Binding.Path son equivalentes ya que ambos terminan configurando el Binding.Path , uno a través del constructor de Binding parametrizado y el otro directamente a través de la propiedad. Lo que ocurre internamente es muy diferente, aunque como Binding.Path no es solo una cadena que en ambos casos Binding.Path a la propiedad, es un PropertyPath .

Cuando se analiza el XAML, los convertidores de tipo se utilizan para convertir las cadenas en los tipos esperados por las propiedades. Por lo tanto, cuando use Path= a PropertyPathConverter creará una instancia para analizar la cadena y devolver un PropertyPath . Ahora aquí está la diferencia:

  • Binding(string path) invoca public PropertyPath(string, Object[])
  • PropertyPathConverter invoca PropertyPathConverter internal PropertyPath(string, ITypeDescriptorContext)

(En el caso del constructor de Binding el Object[] estará vacío)

¿Cómo es esto importante?

Si, por ejemplo, tienes varios indexadores en una clase, por ejemplo, uno que espera una string y uno que espera una int e intentas lanzar el valor para apuntar a la última, el reparto no funcionará:

 {Binding [(sys:Int32)0]} 

The PropertyPath carece de ITypeDescriptorContext porque el constructor público se invoca para que el tipo System.Int32 no se pueda resolver desde el string sys:Int32 .

Si usa Path= sin embargo, se usará el convertidor de tipo en su lugar y el tipo se resolverá utilizando el contexto, por lo que esto funcionará:

 {Binding Path=[(sys:Int32)0]} 

(¿No son divertidos los detalles de implementación?)

Quieren decir lo mismo. Donde difieren es en cómo se instancia y se rellena el objeto de enlace.

 {Binding Path=Foo} 

crea una instancia de enlace utilizando su constructor sin parámetros, y luego establece la propiedad de la ruta de la instancia.

 {Binding Foo} 

crea una instancia de enlace utilizando su constructor de parámetro único y pasa el valor “Foo” a ese parámetro de constructor. El constructor de un solo parámetro solo establece la propiedad Path, por lo que las dos syntax son equivalentes.

Es muy similar a la syntax para atributos personalizados, donde también puede pasar parámetros de constructor y / o establecer valores de propiedad.

No hay diferencia semántica, la primera propiedad del enlace se interpretará como la propiedad “Ruta” si no se proporciona ningún nombre de propiedad.

Es una cuestión de estilo de encoding.

Actualizar

Se eliminó la oración “Es la propiedad predeterminada”.

Me doy cuenta de que no hay soporte formal para “propiedades predeterminadas”, pero el escenario a menudo se denomina “propiedad predeterminada” y es compatible con la convención.

Ejemplo, a partir de la documentación de MSDN para la propiedad Path de la extensión de marcado de enlace:

La extensión de marcado de enlace utiliza Binding.Path como una “propiedad predeterminada” conceptual, donde Path = no necesita aparecer en la expresión.

No creo estar equivocado y completamente equivocado al usar esta terminología como se sugiere. También entiendo cómo se implementa.

No creas que haya alguna diferencia, espera que tal vez el segundo sea más explícito.