Usuario
Bloqueo del UI con el Context Menu

Pregunta
-
Buenas Compañeros,
queria comentaros una duda sobre algo que en principio es relativamente sencillo pero me está dando problemas. Tengo un listbox con elementos de una clase determinada, asociada a cada elemento tengo un context menu con un solo menu-item ("eliminar"). El proceso de eliminar puede ser costoso porque consulto en base de datos y puede tardar unos segundos. Para hacer más agradable la espera al usuario he intentado introducir un progressbar customizado o un textblock avisador "Cargando" pero no me aparecen desde el mismo momento que hago un "tap" sobre el menu-item "eliminar". Para que esté más optimizado he puesto en un hilo secundario (backgroundworker) la consulta a base de datos.
He probado de varias maneras pero no hay forma que sea instantaneo la respuesta de aparición del progressbar al darle a menu-item del context menu. Debo decir que utilizo progress bar desde otros objectos y me van instantaneamente, por lo que deduzco que se produce un bloqueo de la UI al estar en el context menu. ¿Teneis alguna idea?
saludos
Cuanto más sabes, más ignorante te crees.
Todas las respuestas
-
Hola Pedro,
lo primero, ¿has comprobado que tu progress bar o textblock se muestran correctamente? (puedes probarlo sin llamar al código del tap del menú item y dejandolos visibles)
por otro lado, ¿estás seguro de que todo el código que ejecutas en el evento Tap del menu item se ejecuta en el hilo secundario o haces alguna tarea mas?
Quizá haya alguna otra tarea la que este bloqueando la UI
Salu2
@ayus -
Hola Alberto,
efectivamente comprobé que se mostraba que no en el momento que clicklaba sino al tiempo, es como que el context menu dejaraba bloqueada la UI porque he tenido que poner un sleep para poder ver mejor lo que pasaba. Nada más abrir el "menuItem_click" activo el progressbar o hago visible el textblock.
He pensando en algún converter porque realmente no se me ocurre otra cosa. ¿Algo sobre el ModelView?
saludos
Cuanto más sabes, más ignorante te crees. -
-
Este es el código que ejecuto desde el menuitem_click .
private void ContextualEliminar_Click(object sender, RoutedEventArgs e) { barraprogreso.show(); tipo_carga = 1; HiloSecundario = new BackgroundWorker(); HiloSecundario.DoWork += new DoWorkEventHandler(HiloSecundario_DoWork); HiloSecundario.RunWorkerCompleted += new RunWorkerCompletedEventHandler(HiloSecundario_RunWorkerCompleted); HiloSecundario.RunWorkerAsync(); }
El "dowork" y "completed" contienen esto :void HiloSecundario_DoWork(object sender, DoWorkEventArgs e) { Dispatcher.BeginInvoke(() => { //Hago todo lo que tengo que hacer... (esto se ejecuta perfectamente). }); } void HiloSecundario_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { BarraProgreso.Hide(); }
Esto también lo he probado con un Grid - textblock imitando a una barra de progreso pero el resultado es el mismo. Es un problema de bloqueo de UI o de no actualización de la UI. Habia pensado en un converter pero me parece algo complejo en esta situación o fuera de sitio.saludos ;)
Cuanto más sabes, más ignorante te crees. -
Hola de nuevo,
quizá el problema esté en que lo que haces en el DoWork, lo estás haciendo con el Dispatcher.BeginInvoke, lo que al final se ejcutará en el thread de UI.
Prueba a ejecutar el código que tarda mucho, fuera del Dispatcher.BeginInvoke para que se ejcute realmente en el hilo del backgroundworker. Solamente llama al dispatcher cuando tengas que actualizar algo en los controles del la UI, por ejemplo el valor del progressbar.
Algo así
void HiloSecundario_DoWork(object sender, DoWorkEventArgs e)
{//Hago todo lo que tengo que hacer... (esto se ejecuta perfectamente).
Dispatcher.BeginInvoke(() =>
{// Llamadas a actualizaciones de la UI, por ejemplo cambiar el progressbar.
});
}
No sé si puedes probar esto y ver si funciona.Salu2
@ayus -