Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Cambio bidireccional de valores en c#

Iniciado por XÑA, 05 de Octubre de 2011, 12:05:27 PM

« anterior - próximo »

XÑA

Bueno, explico el tema:

Tengo una clase con variables, por ejemplo, la clase Persona, que tiene una propiedad que es Edad.
Por otro lado tengo en el editor un control para modificar esta propiedad. El control es de tipo numérico que tiene una propiedad que es Valor.

Lo que quiero hacer es lo que hace Flex, poder decir que si cambio Edad en la instancia de persona, me cambie automáticamente en el control.

Mis preguntas son:
1. ¿alguien se le ocurre un método mejor?
2. ¿Cómo creo un diccionario para que la búsqueda sea más rápida?
3. ¿Cual sería el código de la reflexión?

Gracias!!


   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();

           myObject m = new myObject();

           MyControl c = new MyControl();

           ProxyVars.Add(m, "Valor", c, "Valor");

           m.Valor = 100; // Automáticamente me debería actualizar el valor de c.Valor
       }
   }

   public class myObject
   {
       float valor;

       public float Valor { get { return valor; } set { valor = value; ProxyVars.Update(this, "Valor"); } }
   }

   public class MyControl
   {
       float valor;

       public float Valor { get { return valor; } set { valor = value; ProxyVars.Update(this, "Valor"); } }
   }

   public class Element
   {
       public object A;
       public string PropertyA;
       public object B;
       public string PropertyB;
   }
   public static class ProxyVars
   {
       public static List<Element> Dictionary;

       public static void Add(object a, string propertyA, object b, string propertyB)
       {
           Element element = new Element();
           element.A = a;
           element.PropertyA = propertyA;
           element.B = b;
           element.PropertyB = propertyB;

           Dictionary.Add(element);
       }

       public static void Update(object a,string property)
       {
           foreach (Element element in Dictionary)
           {
               if(element.A==a)
                   if (element.PropertyA == property)
                   {
                       // usando reflexión asignar la propiedad de b con el valor de la propiedad de a

                       return;
                   }

               if (element.B == a)
                   if (element.PropertyB == property)
                   {
                       // usando reflexión asignar la propiedad de b con el valor de la propiedad de a

                       return;
                   }
           }
       }
   }

Vicente

#1
La forma de hacer esto en C# seria como lo hace WPF, utilizando Bindings, DependencyProperties y INotifyPropertyChanged. Lo malo que esto para hacerlo bien te toca tirar bastante código...

Te dejo un articulo que habla de los Bindings de WPF en bastante detalle para que veas un poco como funciona:

http://msdn.microsoft.com/en-us/library/ms752347.aspx

XÑA

Gracias, ha sido interesante la lectura. En realidad no necesito ni quiero Binding, porqué el engine NO debe tener código que no sea imprescindible. Creo que es el editor el que tiene que tener toda esa funcionalidad, y la ventaja que tengo es que en cada fotograma actualizo el GUI, con lo que lo que voy a hacer es relacionar desde el GUI el objeto que se modifica en el engine, de forma que desde el engine no tienes que hacer nada, porqué el GUI se encarga de mirar si hay cambios en valores y actualizarlos en el engine.

Lo he probado y funciona... ;)

blau

Yo lo que hago es usar lambdas y eventos, y no es complicado, e incluso lo podrias automatizar con refelxion.

Yo por cada propiedad defino un evento con el nombre de la propiedad mas "Changed", y un metodo virtual protegido con "On"+el nombre del evento.

public event Action NameChanged;
public string Name {
    get {return _name; }
    set {
         if (_name!=value) {
                _name = value;
                  OnNamechanged();
          }
     }
}

protected virtual OnNameChanged()
{
     if (NameChanged!=null) NameChanged();
}


Luego a la hora de vincular el control.

           myObject m = new myObject();

            MyControl c = new MyControl();

           m.NameChanged += () => c.Text = m.Name;
           
           c.TextChanged += ()=> m.Name = c.Text;  // Si, puede haber problemas, pero por eso si se comprueba en la propiedad Name que           
                                                                                       // realmente haya cambiado. Podrias crear un metodo para cambiar el nombre sin que se
                                                                                      // desaten los eventos, o simplemente anular la suscripcion del control al objeto
                                                                                       // temporalmente mientras haces este cambio.









Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.