Vassag0

Miembro habitual
Mensajes
241
Reacciones
0
No se si alguno usará el C# .NET para echarme un cable con una duda que tengo.

Yo siempre he programado en VB .NET, pero ahora por temas laborales estoy con el C# .NET. El caso es que yo hago aplicaciones de gestión, por lo que en VB .NET tenia, por ejemplo, un modulo con las funciones de llamadas a base de datos (modificar, alta, transacciones...).

Ahora que paso a trabajar en C# .NET quiero pasar mis módulos de VB .NET a clases en C# .NET y sus void.

Todo va perfecto salvo porque desde un void en la clase invoco a varios TextBox del formulario para completarlos con los datos. Todo funciona sin un error, salvo que los TextBox no me ponen el texto.
Si uso el mismo código para pero llenando los TextBox en el formulario, llamando al DataRow que previamente he cargado con los datos en la clase, funciona sin problema. Pero el caso es que yo quiero llamar a los TextBox desde la clase.

He probado incluso a realizar un código sencillo, que es intentar llenar un TextBox desde un void en la clase, invocándolo en el form... y nada, no muestra nada.

¿Alguien me puede guiar como se hace esto bajo C# .NET?

Gracias.
 
Tal como lo dices me cuesta saber a que te refieres (o igual es el alcohol de la cena), pero si me pasas el código en VB a findor arroba gmail punto com, le pego un vistazo y te lo traduzco en un plis... (para algo llevo más de 5 años de consultor en .net... :cuniao )
 
Ahora con un poco más de calma esto me suena al clásico parámetro por valor o por referencia...

A ver si he entendido el problema... tú tienes un formulario y una clase aparte. El formulario invoca a la clase pasándole los textboxes(?) como parámetros(?)

El tema es que en VB.NET, aunque un parámetro esté definido como ByVal, en realidad, si es de una clase que no sea básica como un control, un dataset, etc, realmente equivale a un ByRef, aunque le pongas ByVal.

En c# esto no pasa, así que los textboxes que pasas como parámetro has de definirlos como ref, si no no te los cambiará.

Si no es esto o no he entendido bien el problema, házmelo saber y miramos algo más. :hola
 
Lo primero muchísimas gracias por tu ayuda.

Sobre el tema no se si me he explicado correctamente sobre lo que quiero hacer. En principio no es pasarle parámetros, sino texto. Te pongo el código en C# para que veas lo que pretendo.

En el Form1:
Insertar CODE, HTML o PHP:
//Incluyo la clase
bbdd bbdd = new WindowsFormsApplication1.bbdd();

//En el evento onclick llamo a estos metodos de la clase. No pongo todo el código por abreviar.
                bbdd.consultar_datos("select * from demandantes");
                bbdd.mostrar_datos(0);
                bbdd.conn.Close();

En la clase:
Insertar CODE, HTML o PHP:
        #region conexion bbdd
        //Creamos una función de conexión a la bbdd
        public void conectar()
        {
            //Si existe la conexión la cerramos antes de crearla
            if (conn != null)
				{
					conn.Close();
				}
            
            //Generamos la cadena de conexión con sus parametros
            string connStr;
            connStr = string.Format("server={0};user id={1}; password={2}; database=***; pooling=false", host, usuario, pass);
        
            //Preparamos la captura de cualquier evento
            try
                {
            //Abrimos la conexión con los parametros
            conn = new MySqlConnection(connStr);
            conn.Open();
                }

            //oopppss!!! no pudimos conectar
            catch (MySqlException ex) { MessageBox.Show("Error al conectar al servidor: " + ex.ToString()); }

          }
        #endregion


        #region Consulta de datos
        //Función para consultar datos segun la sentencia SQL dada
        public void consultar_datos(string consulta)
        {
            //Llamamos a la función de conexión a bbdd
            conectar();

            //Preparamos la captura de cualquier evento
            try
                {
                //Llenamos la tabla de datos procedentes de nuestra consulta
                da = new MySqlDataAdapter(consulta, conn);
                cb = new MySqlCommandBuilder(da);
                
                data = new DataTable();
                da.Fill(data);
                }


            //ooopppss!!! no hay datos por esos criterios
            catch(InvalidCastException){MessageBox.Show("La consulta no recupero datos con esos parametros");}

            //oopppss!!! no pudimos conectar
            catch (MySqlException ex) { MessageBox.Show("Error al conectar al servidor: " + ex.ToString()); }

        }
        #endregion


        #region Mostrar datos
        //Función para consultar datos segun la sentencia SQL dada
        public void mostrar_datos(int f)
        {

            try
            {
                if (f < 0 || data.Rows.Count - 1 < 0)
                {
                    return;
                }

                dr = data.Rows[f];
          
               //Incluyo el Form1 dentro de la clase
               Form1 form1 = new WindowsFormsApplication1.Form1();

               //Intento mostrar los registros en el array (m_TextBox1) de textbox.
                int i;
                for (i = 0; i <= m_TextBox1.Count - 1; i++)
                {
                    form1.m_TextBox1[i].Text = dr[i + 1].ToString();
                }

            }
            //oopppss!!! no pudimos conectar
            catch (MySqlException ex) { MessageBox.Show("Error al conectar al servidor: " + ex.ToString()); }
        }
        #endregion

Como ves en el ejemplo el problema radica en la clase al intentar pasarle texto al array de textbox: m_TextBox1.Text

Incluso si intento pasarle texto al TextBox1_1 directamente desde la clase con: form1.TextBox1_1.Text = "hola". Tampoco hace nada, se ejecuta sin errores el código pero no muestra el texto. El TextBox1_1 esta marcado como publico en el Form1. Sino si arroja un error de objeto inaccesible.

Por contra si lleno el array m_TextBox1 desde el Form1, después de lanzar el método bbdd.mostrar_datos() funciona sin problemas.
 
Vale, ya veo por donde vas, el problema que tienes aquí es que tienes dos instancias diferentes del formulario...

Realmente, en el código, cuando pones :

Insertar CODE, HTML o PHP:
//Incluyo el Form1 dentro de la clase
Form1 form1 = new WindowsFormsApplication1.Form1();

No estás usando una referencia al formulario original, sino que realmente estás generando otro formulario como variable local al método y sólo tiene validez en ese ámbito, así que al salir del método esa variable se pierde.

Para que el método mostrar_datos sea capaz de encontrar los textboxes necesita recibir como parámetro la instancia real del formulario... Lo que yo haría con ese código:

Desde el formulario:
Insertar CODE, HTML o PHP:
//Incluyo la clase
bbdd bbdd = new WindowsFormsApplication1.bbdd();

//En el evento onclick llamo a estos metodos de la clase. No pongo todo el código por abreviar.
                bbdd.consultar_datos("select * from demandantes");
                bbdd.mostrar_datos(0, this); //Se pasa al método la instancia del formulario que es donde se ejecuta este evento
                bbdd.conn.Close();

desde la clase:
Insertar CODE, HTML o PHP:
#region Mostrar datos
        //Función para consultar datos segun la sentencia SQL dada
        public void mostrar_datos(int f, ref System.Windows.Form form1) //Pasas por referencia el formulario
        {

            try
            {
                if (f < 0 || data.Rows.Count - 1 < 0)
                {
                    return;
                }

                dr = data.Rows[f];
          
               //Incluyo el Form1 dentro de la clase
               //Form1 form1 = new WindowsFormsApplication1.Form1();
               //No uses el new, sinó el que viene por parámetro.

               //Intento mostrar los registros en el array (m_TextBox1) de textbox.
                int i;
                for (i = 0; i <= m_TextBox1.Count - 1; i++)
                {
                    form1.m_TextBox1[i].Text = dr[i + 1].ToString();
                }

            }
            //oopppss!!! no pudimos conectar
            catch (MySqlException ex) { MessageBox.Show("Error al conectar al servidor: " + ex.ToString()); }
        }
        #endregion

El porqué esto va de otra forma en VB.Net es una de esas cosas con las que me peleo desde hace tiempo. VB.Net tiene una serie de limitaciones y funcionamientos autoimpuestos para aumentar la compatiblilidad en aplicaciones migradas desde VB6, eso implica cosas como que, mientras en c# las operaciones lógicas And y Or funcionan en corticircuito, en VB no, y hay que usar los AndAlso y los OrElse para que sea equivalente. También implica que la traducción "literal" de código no siempre hace lo mismo.

Aparte de la explicación pedante, espero que lo otro te sirva. :hola
 
Muchas gracias de nuevo por tu explicación.

El tema es que la referencia da error:
ref System.Windows.Form form1

En principio me dice que "From" no lo reconoce. Pruebo con ref System.Windows.Forms form1, pero sigue dando error.

He probado también con ref System.Windows.Forms.Form form1, pero nada, da error.
 
Coñe, que tonto... :doh

Es mucho más fácil que eso...

public void mostrar_datos(int f, ref WindowsFormsApplication1.Form1 form1)

Si ya tienes una clase para la variable, pues usémosla... :doh (me he obcecao con el Windows.Forms...)
 
De nuevo gracias... pero sigue sin ir .

El código queda así. En el evento onclick en el formulario:
Insertar CODE, HTML o PHP:
bbdd.mostrar_datos(0, this);

En el método de la clase:
Insertar CODE, HTML o PHP:
        public void mostrar_datos(int f, ref WindowsFormsApplication1.Form1 form1)
        {

            try
            {
                if (f < 0 || data.Rows.Count - 1 < 0)
                {
                    return;
                }

                dr = data.Rows[f];

                int i;
                for (i = 0; i <= form1.m_TextBox1.Count - 1; i++)
                {
                    form1.m_TextBox1[i].Text = dr[i + 1].ToString();
                }

            }
            //oopppss!!! no pudimos conectar
            catch (MySqlException ex) { MessageBox.Show("Error al conectar al servidor: " + ex.ToString()); }
        }

Y me devuelve estos errores:
 
Vale, vamos a ver. Los errores 1 y 2 deberían marcharse usando esto:

bbdd.mostrar_datos(0, ref this);

Fallo mio. Los otros dos debe ser porque usas el método mostrar_datos desde algún otro sitio y deberías usar la misma llamada desde todos los sitios. Creo que con eso debería, por lo menos, arreglarse los problemas de compilación. Sin embargo...

Y ahora me pongo la corbata de consultor, me pongo purista y te recomiendo (cosa que puedes ignorar) lo que yo REALMENTE haría es:

A nivel de arquitectura, no es "aceptable" que un servicio (mostrar_datos), tenga acceso al formulario, lo lógico y deseable sería que el método no fuese un void, sinó que devolviese un Datarow :

public DataRow mostrar_datos(int f)

y este código estuviese en el evento del botón:

for (i = 0; i <= this.m_TextBox1.Count - 1; i++)
{
this.m_TextBox1.Text = dr[i + 1].ToString();
}

Lo dicho, esto último puedes ignorarlo totalmente porque implica hacer cambios en la estructura, pero como soy un puñetero purista, tenía que decirlo... :P
 
De nuevo gracias... pero de nuevo sigue sin ir. Indica que <this> es de solo lectura. Yo creo que desisto.

Ademas si me dices que lo otro es mas purista, me quedo con lo otro.

En VB .NET uso los controles desde la función en el modulo por economizar el código. Ya que esa función es llamada por varios eventos.

En C#, ante la imposibilidad de conseguirlo, lo tengo de la manera que me has comentado como mas purista. Bueno sin el DataRow, porque poniéndolo me daba error, por eso uso void. Pero yo estaba encabezonado que la manera purista seria llamando a los controles desde el método de la clase, al usar menos código... aun me queda por aprender :)

Muchas gracias por toda la ayuda. Es una suerte y un placer contar con los consejos de alguien de tu experiencia.

Seguiré peleándome con el C#, con lo bien que estaba con mi VB .NET :llanto
 
http://es.wikipedia.org/wiki/Arquitectu ... es_niveles

Yo es que cuando me pongo purista hay pocos que me aguanten, así que... :P

La teoría dice que la capa de presentación (formulario) puede tener acceso a los datos, pero no al revés, así que aseguras que si quieres recuperar los datos desde otro formulario distinto, cada uno hace uso de lo que necesita.

Si no te detecta el datarow, prueba a ponerle el espacio de nombres completo System.Data.Datarow, en todo caso eso ya es un tema de que te falta alguna referencia o algún using. Mi táctica es hacer que el mostrar_datos devuelva lo que recupera (return data.Rows[f];) y ahí acabe, y que el único sitio desde donde se accede a los textboxes es desde el Form1.

En todo caso, me hubiese gustado ser de más ayuda, aunque esto me ayuda en mi pelea anti VB.Net... :cuniao
 
Pues muchísimas gracias por los consejos y el adoctrinamiento.

He probado como dices (return data.Rows[f];) y todo perfecto. Me gusta. Economizo código y una variable.

Siempre que programo, por comodidad para los cambios, suelo hacerlo en "capas". Pero, por lo que veo, de manera poco ortodoxa.
Aprovecharé para revisar de forma mas escrupulosa el código.

De nuevo gracias.
 
Hola a todos.

La semana que viene tengo una reunión importante para la que necesito tener el entorno Visual Studio, la versión más reciente que sea posible, lo más curioseado posible.

No es necesario formarme (no da tiempo) ni nada de eso, simplemente familiarizarme con el entorno, ver sus posibilidades, como se integra con Team Foundation Server y poco más.

Mi idea es instalarme un Win7 u 8 en VMWare, que tengo instalado en el Mac, y allí instalar el Visual Studio. Y revisar todo lo que me dé tiempo hasta la reunión.

¿Consejos? ¿Alguna ayuda por mp para obtenerlo todo? :cortina

Agradezco cualquier ayuda pues es muy importante que la reunión salga bien. Gracias mil. :ok
 
En ese punto ya estoy. ;) Gracias.

Mi verdadero problema es qué Windows me instalo que sea más adecuado, imagino que un 7, y de donde lo saco.

Voy a mirar si del mismo modo torrentiano los hay ya activados...
 
Voy a mirar.. Ya lo tuve instalado y me expiró.... Voy a ver si puedo otra vez o si el torrente me da una alegría.
 
Si instalas una máquina virtual nueva, no va a saber si te expiró o no el otro que instalaste. Tendrás otro periodo de prueba.

Manu1oo1
 
Voy a ello... si la version Torrentiana no va.... que es mi plan A. :juas

Gracias.
 
Con XP puedo correr entonces Visual Studio 2010???

Si es así ya lo tengo!!!!!
 
Arriba Pie