Foros del Web » Programación para mayores de 30 ;) » .NET »

C# Clase con Eventos, error actualizando control.

Estas en el tema de C# Clase con Eventos, error actualizando control. en el foro de .NET en Foros del Web. Hola buenas tardes !! Tengo una clase con eventos, declaro el objeto en mi Formulario windows y establezco los eventos de ese control y los ...
  #1 (permalink)  
Antiguo 29/12/2007, 07:50
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 11 meses
Puntos: 7
C# Clase con Eventos, error actualizando control.

Hola buenas tardes !!

Tengo una clase con eventos, declaro el objeto en mi Formulario windows y establezco los eventos de ese control y los programo.

Pero dentro de ese Evento, actualizo un listbox para ir metiendo los datos que recibo del evento. Bueno, pues si el evento es de un boton, como siempre, si me hace las cosas bien y me rellena los datos en el listbox.

Pero si capturo los datos del evento de este objeto, al actualizar el listbox me da error de un acceso desde otro hilo no esta permitido. Y tengo que poner el :

CheckForIllegalCrossThreadCalls = False;

Pero... por que un evento de boton si funciona bien y uno de mi objeto no?
__________________
Charlie.
  #2 (permalink)  
Antiguo 30/12/2007, 22:07
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Re: C# Clase con Eventos, error actualizando control.

Hola.

lo que sucede es lo siguiente cuando creas la asociacion con el control boton estas utilizando el evento OnClicked.

La solucion para eventos que ocurren fuera del ambito del thread de la aplicacion es crear un evento e invocarlo con el metodo BeginInvoke dentro de este pasar los parametros y sera muy simple actualizar el problema.

Si estas utilizando hilos o algun backgroundworker esta puede ser la causa.

Saludos
Peterpay
  #3 (permalink)  
Antiguo 31/12/2007, 06:40
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 11 meses
Puntos: 7
Re: C# Clase con Eventos, error actualizando control.

Haber, más o menos entiendo lo que me dices, lo que no entiendo es el PORQUE.

Es decir, tanto mi clase, como la clase del botón no están definidas propiamente en mi proyecto, sino que están creadas en otros proyectos.

El Boton esta dentro del System.Windows.Forms.dll (O algo asi será) y mi clase esta en el proyecto HeviaServerXml.dll.

Entonces, por que uno si funciona y el otro no....

Bien y sobre lo del BeginInvoke... ¿No habrás hecho tu algún ejemplo que me puedas mostrar, verdad? jejeje

Desde ya, muchas gracias por las respuestas dadas.

Un saludo.
__________________
Charlie.
  #4 (permalink)  
Antiguo 31/12/2007, 06:46
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Re: C# Clase con Eventos, error actualizando control.

checate el ejemplo que puse en el post del progressbar aqui mismo.

lo q pasa es esto cuando creas tu aplicacion el boton es parte de tu forma. pero muy probablemente estes invocando la carga de datos en otro hilo, es por ello q tienes ese error de comunicacion interhilos, facilmente solucionable.

Lo q necesitas hacer es uno, ya q tu carga esta en otro hilo (hijo ) es invocar el delegado q actualizara tu forma. si es un objeto facilmente puedes obtener la propiedad a mostrar

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

private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_Prog ressChanged);
this.mireportador += new ReportaAvance(Form1_mireportador);
backgroundWorker1.WorkerReportsProgress = true;
}

void Form1_mireportador(int avance)
{
progressBar1.Value = avance;
}

public delegate void ReportaAvance (int avance);
public event ReportaAvance mireportador;

void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
BeginInvoke(mireportador, e.ProgressPercentage);
}


// Tu codigo puede ir aqui. y en vez de reportar un avance en el progressbar solo pasas un valor como el nombre de la fila de tu datareader o estructura. void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{

System.Threading.Thread.Sleep(i * 1000);

backgroundWorker1.ReportProgress(i);
}
}

private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
  #5 (permalink)  
Antiguo 31/12/2007, 06:47
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Re: C# Clase con Eventos, error actualizando control.

el backgroundworker es meramente ilustrativo.

lo que puedes hacer es solo crear tu evento , tu delegado y actualizar los datos.

en un listbox o combobox.
  #6 (permalink)  
Antiguo 02/01/2008, 02:11
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 11 meses
Puntos: 7
Re: C# Clase con Eventos, error actualizando control.

Bueno, muchas gracias por tu documentación Peterpay, al final lo solucioné tal como me has comentado:

Código:
//Creo el deletado para actualizar la caja de texto, si se ejecuta el evento NuevaConexion de mi objeto.
public delegate void DelegadoNuevaConexion(string txtIpCliente, int puertoCliente);


//Implemento el evento de mi objeto en el formulario.
        private void objHeviaServer_NuevaConexion(string txtIpCliente, int puertoCliente)
        {
            DelegadoNuevaConexion delegadoNuevaConexion = new DelegadoNuevaConexion(NuevaConexionCliente);
            if (txtEventos.InvokeRequired)
                txtEventos.Invoke(delegadoNuevaConexion, new object[] { txtIpCliente, puertoCliente });
            else
                txtEventos.Text += "[NUEVA CONEXION] " + txtIpCliente + ":" + puertoCliente;
        }




//Si mi caja de texto requiere de Invocación, llamaré a este evento enlazado con el delegado.
public void NuevaConexionCliente(string txtIpCliente, int puertoCliente)
        {
            txtEventos.Text += "[NUEVA CONEXION] " + txtIpCliente + ":" + puertoCliente;
        }


Vale, con esto me funciona a la perfección, pero... ¿Hay alguna forma de poder implementar en mi clase algún atributo o algo para no tener que poner en mi formulario todo el tema del Delegate?

Lo que quiero es no tener que escribir todo ese código, sino que conseguir un funcionamiento similar al Evento OnClick de un botón, que ahí ya puedo escribir lo que quiera, sin necesidad de crear delegados.

En fin, si hay alguna forma(Sin usar el CheckForIllegals..) estaría bueno conocerla, asi no tendría que crear un Delegado y un método nuevo para cada evento de mi objeto...

En fin, por lo demás, gracias por su solución.

Un cordial saludo.
__________________
Charlie.
  #7 (permalink)  
Antiguo 02/01/2008, 06:49
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Re: C# Clase con Eventos, error actualizando control.

Claro que puedes hacer lo mismo, como en OnClick puedes poner tu delegado, y tu evento en la clase que definiste y solo hacer un evento como obj.EnActualiza+=new OnEnActualiza(tumetodo);

y usar tu base.Metodo();

pero lo mejor es solo suscribir tu metodo 1 vez a la carga y listo.

Saludos
Peterpay
  #8 (permalink)  
Antiguo 02/01/2008, 08:02
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 11 meses
Puntos: 7
Re: C# Clase con Eventos, error actualizando control.

Perdona Peterpay, pero... no entiendo como dices... Si pudieras explicarmelo un poco más detalladamente te lo agradecería muchísimo, de verdad.

Actualmente tengo en mi clase lo siguiente:
Código:
public delegate void EventoNuevaConexion(string txtIpCliente, int puertoCliente);
public event EventoNuevaConexion NuevaConexion;



//EN OTRA PARTE DEL CODIGO ES CUANDO LANZO EL EVENTO:
NuevaConexion("132.0.0.1", 1880);


Y en el Formulario tengo:
Código:
private void btnIniciar_Click(object sender, EventArgs e)
{
       objHeviaServer.NuevaConexion += new HeviaServerXml.ClsServidor.EventoNuevaConexion(objHeviaServer_NuevaConexion);
}







        private delegate void DelegadoNuevaConexion(string txtIpCliente, int puertoCliente);
        private void objHeviaServer_NuevaConexion(string txtIpCliente, int puertoCliente)
        {
            DelegadoNuevaConexion delegadoNuevaConexion = new DelegadoNuevaConexion(NuevaConexionCliente);
            if (txtEventos.InvokeRequired)
                txtEventos.Invoke(delegadoNuevaConexion, new object[] { txtIpCliente, puertoCliente });
            else
            {
                txtEventos.Text += "[NUEVA CONEXION] " + txtIpCliente + ":" + puertoCliente;
                txtEventos.Text += Environment.NewLine;
            }
        }
        private void NuevaConexionCliente(string txtIpCliente, int puertoCliente)
        {
            txtEventos.Text += "[NUEVA CONEXION] " + txtIpCliente + ":" + puertoCliente;
            txtEventos.Text += Environment.NewLine;
        }
Si me puedes comentar como reducir el código del Formulario te lo agradecería.

Saludos.
__________________
Charlie.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:37.