Hola ¿alguien sabe si hay alguna incorporado clases para la resolución de un objeto dependiente de un bindingexpression y es DataItem y la ruta de la propiedad?

Estoy tratando de escribir una Mezcla de 3 comportamiento para los cuadros de texto que automáticamente invoca a los métodos de un objeto vinculado a la propiedad text del cuadro de Texto.

El cuadro de texto está ligado a una propiedad de una clase viewmodel. Lo que quiero hacer es resolver el viewmodel de la clase a partir de la expresión de enlace y, a continuación, hacer llamadas en esto.

Puedo recuperar primero la expresión de enlace a partir del comportamiento del objeto asociado así:

private BindingExpression GetTextBinding()
{
    return this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
}

De haber hecho esto, si nos fijamos en la expresión de enlace, podemos ver que tiene una referencia en el contexto de datos a través de la expresión de enlace de Datos de la propiedad.

Además, tenemos la ruta de acceso relativa de la propiedad, que está enlazado en la expresión de enlace de padres de unión.

Así, podemos obtener esta información:

var bindingExpression = GetTextBinding();
object dataContextItem = bindingExpression.DataItem;
PropertyPath relativePropertyPath = bindingExpression.ParentBinding.Path;

Ahora, esta ruta de la propiedad podría ser potencialmente un anidada y complejo camino, que me gustaría mucho para evitar tener que re (?)la aplicación de la resolución de. He buscado en todo el .RED de documentación y rebotó en torno a las asambleas con reflector, todo fue en vano – no puedo encontrar lo que seguramente debe existir – tiene que haber alguna clase que realiza la resolución de la ruta de acceso para el dataitem (el contexto de datos).

¿Alguien sabe donde esta pueda existir? Alguna sugerencia para las formas alternativas de resolver el objeto enlazado?

Nota, estoy tratando de conseguir en el objeto enlazado que es el padre de la propiedad enlazada (de la cadena, en este caso) – yo obviamente se pueden conseguir fácilmente en el valor del límite, pero es el padre el que necesito.

Gracias de antemano por cualquier ayuda!
Phil

InformationsquelleAutor Phil | 2009-10-11

5 Comentarios

  1. 24

    A continuación es una rápida implementación de un método de extensión que va a hacer exactamente lo que usted está buscando. No pude encontrar nada relacionado con esto. El siguiente método siempre devuelve null si por alguna razón el valor no puede ser encontrado. El método no funciona cuando la ruta de acceso incluye []. Espero que esto ayude!

    public static T GetValue<T>(this BindingExpression expression, object dataItem)            
    {
        if (expression == null || dataItem == null)
        {
            return default(T);
        }
    
        string bindingPath = expression.ParentBinding.Path.Path;
        string[] properties = bindingPath.Split('.');
    
        object currentObject = dataItem;
        Type currentType = null;
    
        for (int i = 0; i < properties.Length; i++)
        {
            currentType = currentObject.GetType();                
            PropertyInfo property = currentType.GetProperty(properties[i]);
            if (property == null)
            {                    
                currentObject = null;
                break;
            }
            currentObject = property.GetValue(currentObject, null);
            if (currentObject == null)
            {
                break;
            }
        }
    
        return (T)currentObject;
    }
    • Gracias zhech, voy a dar que un intento.
    • My2cents, hay una razón de su fallecimiento en el objeto de datos? ¿Por qué no cambiar la firma de método para tomar un parámetro en lugar de dos y obtener los datos de la BindingExpression?
    • Esto no se ve como que va a resolver la propiedad caminos con indizadores, o no?
    • el futuro de prueba de manera que se sitúa por debajo del
  2. 25

    Para la gente en el futuro, los que tropiezan en esta pregunta:

    Cuando .NET 4.5 disponible tendrá un número de propiedades nuevas en el BindingExpression a simplificar en gran medida lo que usted está buscando.

    ResolvedSource – El objeto que está siendo obligado a, útil cuando se tiene un enlace de la fuente como ‘abuelo.el padre de familia.me.Nombre’. Se devuelve el ‘yo’ del objeto.

    ResolvedSourcePropertyName – El nombre de la propiedad en el ResolvedSource que está enlazado. En el caso anterior, «Nombre».

    Del mismo modo, habrá Objetivo, y TargetName propiedades.

    Con estos auxiliar propiedades en BindingExpression usted podría utilizar un poco más corto y mucho más simplificada de la reflexión de que es más probable que en situaciones extremas (indexadores).

    • ¿Sabes si hay de todos modos a la fuerza de la expresión de enlace a la actualización de estas propiedades? Yo estoy en una situación muy peculiar donde estoy, la clonación de unión cuando los controles de datos de los cambios de contexto y obtener el código fuente de la expresión de enlace, sin embargo, estas propiedades parecen ser nulo hasta después de que tanto la propiedad ha cambiado y los datos de contexto de los eventos de cambio.
    • Puedo interpretar que la pregunta de varias maneras. Me gustaría recomendar la puesta en marcha de una nueva pregunta, en vez de añadir aquí.
  3. 10

    Para información adicional, PropertyPath resolución es manejado por un interno de la MS clase llamada PropertyPathWorker, que vive en PresentationFramework en virtud de la SEÑORA Interna.De datos. Si se abre en el Reflector, se puede ver que es bastante complicado, por lo que no recomiendo intentar duplicar su funcionalidad. Es bien junto con el general de Unión de la arquitectura.

    El más robusto para soportar toda la ruta de la propiedad sintaxis–incluyendo adjunto las propiedades de dependencia y jerárquica traversal–es, probablemente, para crear un maniquí de DependencyObject con un DependencyProperty. A continuación, puede crear un Enlace de su «dueño» ruta de acceso de la dummy de propiedad de dependencia, crear un nuevo BindingExpression y, a continuación, llamar a la expresión del UpdateTarget. Es más bien una forma pesada de llevar a cabo lo que, en la superficie, parece una tarea sencilla, pero creo que hay un montón de oculta trampas en el camino de la propiedad rutas de acceso se resuelven por la unión.

    • Gracias Dan, que buena info.
    • Hubiera sido mejor con el código fuente. 🙂
  4. 8

    Creo que este otro StackOverflow solución publicado aquí también puede funcionar para usted.

    Copiado bloque de código de referencia, leer el post original para más detalles proporcionados por Thomas Levesque.

    public static class PropertyPathHelper
    {
        public static object GetValue(object obj, string propertyPath)
        {
            Binding binding = new Binding(propertyPath);
            binding.Mode = BindingMode.OneTime;
            binding.Source = obj;
            BindingOperations.SetBinding(_dummy, Dummy.ValueProperty, binding);
            return _dummy.GetValue(Dummy.ValueProperty);
        }
    
        private static readonly Dummy _dummy = new Dummy();
    
        private class Dummy : DependencyObject
        {
            public static readonly DependencyProperty ValueProperty =
                DependencyProperty.Register("Value", typeof(object), typeof(Dummy), new UIPropertyMetadata(null));
        }
    }
  5. 2

    Como Dan Bryant ya se ha señalado, PropertyPath resolución está estrechamente ligado con el general de unión de la arquitectura.

    Si usted necesita exactamente la misma resolución, como WPF hace, usted probablemente tendrá que usar Thomas Levesque, la respuesta a este pregunta.

    Sin embargo, si en general la ruta de resolución, usted puede utilizar un paquete de nuget Pather.CSharp he desarrollado que hace exactamente eso.

    Que es esencialmente similar a zhech la respuesta, pero más sofisticada.

    Su principal método es Resolve en el Resolver clase. Que pasa en el objeto de destino y un camino como string devuelve el resultado deseado.

    Un Ejemplo:

    IResolver resolver = new Resolver(); 
    var target = new { Property1 = new { Property2 = "value" } };   
    object result = r.Resolve(target, "Property1.Property2");

    También es compatible de acceso a las colecciones a través del índice o diccionario de acceso a través de la llave.

    Rutas de acceso de ejemplo de estos son:

    "ArrayProperty[5]"
    "DictionaryProperty[Key]"

Dejar respuesta

Please enter your comment!
Please enter your name here