2008-09-30 27 views
11

Tengo mi aplicación winform recopilando datos utilizando databinding. Todo se ve bien, excepto que tengo que vincular la propiedadcon el textedit usando una cadena:Obtener el nombre de propiedad de clase

Me.TextEdit4.DataBindings.Add (Nueva System.Windows.Forms.Binding ("EditValue", Me .MyClassBindingSource, "MyClassProperty", True))

Esto funciona bien pero si cambio el nombre de la propiedad de la clase, el compilador obviamente no me avisará.

Me gustaría ser capaz de obtener el nombre de la propiedad por la reflexión, pero no sé cómo especificar el nombre de la propiedad que quiero (sólo conozco la forma de repetición entre todas las propiedades de la clase)

¿Alguna idea?

+0

Solo para asegurarse: desea obtener la propiedad por su nombre, pero el nombre puede haber cambiado? Esto suena como algo que no puede resolverse ... – Darksider

Respuesta

6

Aquí es un ejemplo de lo que estoy hablando:

[AttributeUsage(AttributeTargets.Property)] 
class TextProperyAttribute: Attribute 
{} 

class MyTextBox 
{ 
    [TextPropery] 
    public string Text { get; set;} 
    public int Foo { get; set;} 
    public double Bar { get; set;} 
} 


static string GetTextProperty(Type type) 
{ 
    foreach (PropertyInfo info in type.GetProperties()) 
    { 
     if (info.GetCustomAttributes(typeof(TextProperyAttribute), true).Length > 0) 
     { 
      return info.Name; 
     } 
    } 

    return null; 
} 

... 

Type type = typeof (MyTextBox); 

string name = GetTextProperty(type); 

Console.WriteLine(name); // Prints "Text" 
+0

Maldición, me ganaste ... Estaba a punto de publicar un ejemplo. : -/ –

+0

Textualmente casi lo mismo, podría agregar. –

+0

Konrad Rudolph, hoy perdí ~ 200 rep por razones desconocidas, dame una oportunidad :). ¡Váyanlo arriba! – aku

3

Irónicamente reflexión espera que proporcione nombre de la propiedad para obtener información que es :)

Puede crear atributo personalizado, que se aplican a la propiedad deseada. Entonces podrá simplemente obtener el nombre de la propiedad que tiene este atributo.

+0

¡+1 para un buen uso de los atributos personalizados! –

0

Tendrá el mismo problema al usar la reflexión porque para encontrar la propiedad correcta en todas las propiedades del tipo, tendrá que saber su nombre, ¿verdad?

0

Puede reflejar un tipo, pero no puede reflejar sus miembros, excepto por su nombre.

Si esa fuera la única propiedad, o si supiera con certeza el orden, podría encontrarla por índice, pero en general, una cadena es la manera más segura de hacerlo.

Creo que cambiar el nombre causará una excepción de tiempo de ejecución, pero no estoy 100% seguro, en cualquier caso, esa es probablemente la mejor posibilidad.

Suponiendo que no se produce una excepción de forma automática, puede agregar una depuración. Afirme que comprueba si existe la propiedad con ese nombre, pero de nuevo solo es tiempo de ejecución.

0

1) Especificar el nombre de la propiedad exacta que desee y mantenerlo así

2) un ensayo que implica que el nombre de la propiedad.

8

Si está usando C# 3.0, hay una manera de obtener el nombre de la propiedad de forma dinámica, sin codificado él.

private string GetPropertyName<TValue>(Expression<Func<BindingSourceType, TValue>> propertySelector) 
{ 
    var memberExpression = propertySelector.Body as MemberExpression; 
    return memberExpression != null 
      ? memberExpression.Member.Name 
      : string.empty; 
} 

Dónde BindingSourceType es el nombre de la clase de la instancia de objeto de origen de datos.

A continuación, se puede utilizar una expresión lambda para seleccionar la propiedad que desea enlazar, de manera inflexible:

this.textBox.DataBindings.Add(GetPropertyName(o => o.MyClassProperty), 
           this.myDataSourceObject, 
           "Text"); 

Se le permitirá a refactorizar el código de seguridad, sin frenar todas sus cosas de enlace de datos . Pero usar árboles de expresión es lo mismo que usar la reflexión, en términos de rendimiento.

El código anterior es bastante desagradable y desaprovechado, pero se entiende.

+0

Agradable, pero crea una dependencia de compilación entre la interfaz de usuario y el objeto de origen de datos. – aku

+0

No debería ser un problema ... No estoy seguro de ver por qué la interfaz de usuario no conoce el tipo de objetos que muestra. En MVP/MVC, casi siempre es el caso, incluso si usamos el modelo de presentación. Pero sí, si no puede conocer el tipo de objeto, no puede usar esta solución. –

+0

Estoy de acuerdo con que teclear con fuerza es una buena cosa. Sin embargo, la unión de datos generalmente se basa en nombres textuales. Normalmente se configura a través de algún tipo de GUI, o en el archivo de configuración (XAML, por ejemplo). ¡Aunque tu solución es genial! – aku

Cuestiones relacionadas