2009-04-03 18 views
19

Objective-c/cocoa ofrece una forma de enlace donde las propiedades de un control (es decir, texto en un cuadro de texto) pueden vincularse a la propiedad de un objeto. Estoy intentando duplicar esta funcionalidad en C# w/.Net 3.5.Enlace de datos a un objeto en C#

He creado la siguiente clase muy simple en los archivos MyClass.cs:

class MyClass 
{ 
    private string myName; 

    public string MyName 
    { 
     get 
     { 
      return myName; 
     } 

     set 
     { 
      myName = value; 
     } 
    } 

    public MyClass() 
    { 
     myName = "Allen"; 
    } 
} 

También creé un sencillo formulario con 1 caja de texto y 1 botón. Inicié una instancia de Myclass dentro del código del formulario y creé el proyecto. Utilizando el Asistente de DataSource en Vs2008, seleccioné crear una fuente de datos basada en el objeto y seleccioné el ensamblaje MyClass. Esto creó una entidad de fuente de datos. Cambié el enlace de datos del cuadro de texto a esta fuente de datos; sin embargo, no se logró el resultado esperado (que el contenido del cuadro de texto fuera "allen"). Además, poner texto en el cuadro de texto no actualiza la propiedad del nombre del objeto.

Sé que me estoy perdiendo algo fundamental aquí. En algún momento tendré que vincular mi instancia de la clase MyClass que inicié dentro del código del formulario al cuadro de texto, pero eso no ha ocurrido. Todo lo que he visto en línea parece ignorar el uso de DataBinding con un objeto (o me falta la marca por completo), por lo que cualquier ayuda es muy apreciada.

Editar:

Utilizando lo que he aprendido por las respuestas, miré el código generado por Visual Studio, que tenía la siguiente:

this.myClassBindingSource.DataSource = typeof(BindingTest.MyClass); 

Si comento que fuera y sustituir por:

this.myClassBindingSource.DataSource = new MyClass(); 

Me sale el comportamiento esperado. ¿Por qué es el código predeterminado generado por VS como es? Suponiendo que esto es más correcto que el método que funciona, ¿cómo debo modificar mi código para que funcione dentro de los límites de lo que VS generó?

+0

El código predeterminado se maneja de esa manera para que en tiempo de diseño, todos los controles conozcan los diversos tipos de propiedades que estarán disponibles para el enlace de datos. Pero en tiempo de ejecución necesitas una instancia real. No elimine el código generado automáticamente, jsut establezca un nuevo valor en su formulario onload o soemthing –

Respuesta

15

Debe asignar la fuente de datos del cuadro de texto para que sea su nuevo origen de datos. Pero, además, debe asignar el origen de datos del origen de datos para que sea una instancia de su clase.

MyDataSource.DataSource = new MyClass(); 
TextBox1.DataSource = MyDataSource; 

Eso debería funcionar para su primer pase. Como han mencionado otros, puede que necesite implementar interfaces adicionales en su clase (INotifyPropertyChanged, etc.), si va a modificar las propiedades de la clase mediante cualquier proceso en segundo plano.

Si solo está actualizando las propiedades a través del formulario, entonces no necesita este paso.

+3

TextBox1.DataBindings.Add ("Texto",> Su objeto <, "> PropertyName <"); –

12

Usted debe implementar la interfaz INotifyPropertyChanged a su tipo MiClase: se requiere

public class MyClass : INotifyPropertyChanged 
{ 
    private string _myName; 

    public string MyName 
    { 
     get { return _myName; } 
     set 
     { 
      if(_myName != value) 
      { 
       _myName = value; 
       OnPropertyChanged("MyName"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if(PropertyChanged != null) 
      PropertyChanged(this , new PropertyChangedEventArgs(propertyName)); 
    }  
} 

Esta interfaz para la infraestructura DataBinding si quieres apoyar el enlace de datos simple. La interfaz INotifyPropertyChanged se utiliza para notificar a un 'enlace' que una propiedad ha cambiado, por lo que la infraestructura de enlace de datos puede actuar en consecuencia.

A continuación, puede vincular la propiedad MyName a la Propiedad de texto del cuadro de texto.

0

Parece que es probable que tenga un atributo enlazable en su propiedad MiNombre (y sigue la sugerencia de Frederik también):

[System.ComponentModel.Bindable(true)] 
    public string MyName 
    { 
     get { return _myName; } 
     set 
     { 
      if(_myName != value) 
      { 
       _myName = value; 
       OnPropertyChanged("MyName"); 
      } 
     } 
    } 

Vía: http://support.microsoft.com/kb/327413

0

no tengo ningún código frente a mí , pero creo que la fuente de datos es como una colección. Debe agregar una instancia de MyClass a la fuente de datos, y eso es a lo que se vincularán los campos del formulario. También hay métodos para navegar a través de la fuente de datos a múltiples instancias de MyClass, pero no parece que lo necesites. Verifique los documentos para DataSource.

No creo que deba implementar ninguna interfaz elegante. Me parece recordar que hay un método en la fuente de datos que le permite actualizar o volver a enlazar el elemento actual después de cambiar algunos valores.

3

me sale un mensaje de error en el método DataBinding.Add("TEXT", myObject, myObjectProperty)

Esto es probablemente debido a que se está perdiendo la explícita {get; set;} en la declaración de propiedad!

MALO:

public string FirstName; //<-- you will not be able to bind to this property! 

BUENO:

public string FirstName { get; set; } 
+0

cadena pública FirstName; define un campo, no es una propiedad. Tiene razón al decir que no puede enlazar a un campo, pero no es porque no sea una "propiedad explícitamente declarada". "cadena pública Nombre:" no es una propiedad en absoluto! Si puedo sugerir algo , si puede copiar y pegar el mensaje de error específico que estaba recibiendo, eso podría ayudar a alguien que busca a encontrar su publicación. Gracias por contribuir, estoy seguro de que su nota ayudará a alguien en el futuro. –

0
using System.Collections.Generic; 

public class SiteDataItem 
{ 
private string _text; 
private string _url; 
private int _id; 
private int _parentId; 

public string Text 
{ 
    get 
    { 
     return _text; 
    } 
    set 
    { 
     _text = value; 
    } 
} 

public string Url 
{ 
    get 
    { 
     return _url; 
    } 
    set 
    { 
     _url = value; 
    } 
} 
public int ID 
{ 
    get 
    { 
     return _id; 
    } 
    set 
    { 
     _id = value; 
    } 
} 
public int ParentID 
{ 
    get 
    { 
     return _parentId; 
    } 
    set 
    { 
     _parentId = value; 
    } 
} 
public SiteDataItem(int id, int parentId, string text, string url) 
{ 
    _id = id; 
    _parentId = parentId; 
    _text = text; 
    _url = url; 
} 

public static List<SiteDataItem> GetSiteData() 
{ 
    List<SiteDataItem> siteData = new List<SiteDataItem>(); 
    siteData.Add(new SiteDataItem(1, 0, "All Sites", "")); 
    siteData.Add(new SiteDataItem(2, 1, "Search Engines", "")); 
    siteData.Add(new SiteDataItem(3, 1, "News Sites", "")); 
    siteData.Add(new SiteDataItem(4, 2, "Yahoo", "http://www.yahoo.com")); 
    siteData.Add(new SiteDataItem(5, 2, "MSN", "http://www.msn.com")); 
    siteData.Add(new SiteDataItem(6, 2, "Google", "http://www.google.com")); 
    siteData.Add(new SiteDataItem(7, 3, "CNN", "http://www.cnn.com")); 
    siteData.Add(new SiteDataItem(8, 3, "BBC", "http://www.bbc.co.uk")); 
    siteData.Add(new SiteDataItem(9, 3, "FOX", "http://www.foxnews.com")); 
    return siteData; 
} 
} 

Más detalles se pueden leer dapfor tutorial. com

Cuestiones relacionadas