Jump to content

Alteração do conteudo de uma label


nero_lux

Recommended Posts

Bom dia, estou com uma dúvida mesmo básica. Não consigo alterar dinamicamente o conteudo da minha Label.

Passo a explicar, no meu ecrã de inicialização da aplicação vou efectuar várias verificações do tipo, se o ficheiro de configuração da aplicação existe, se a base de dados existe... A medida que vou efectuar essas verificações prentendo alterar o Content da minha Label, informando o Utilizador da tarefa que está a ser executada.

Assim não funciona:


private void SbCompleted(object sender, EventArgs e)
{

       LblMsg.Content =  "Inicializar os componentes..";
       DoEvents();
       Thread.Sleep(1000);
       LerConfiguracoes();
       WindowLogin FrmLogin = new WindowLogin();
       FrmLogin.Show();

} //SbCompleted

A única solução que encontrei foi associar um MouseDoubleClick à Label e assim já funciona:


private void LblMsg_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{

    LblMsg.Content =  "Inicializar os componentes..";
    DoEvents();
   Thread.Sleep(1000);
   LerConfiguracoes();
   WindowLogin FrmLogin = new WindowLogin();
   FrmLogin.Show();
		// TODO: Add event handler implementation here.
}

O que estou a fazer de errado?

Link to comment
Share on other sites

Boas,

Isso acontece porque o conteúdo dos controlos é alterado de forma assíncrona, através de mensagens processadas pelo Dispatcher do WPF quando a thread está *livre*, e o facto é que a sua thread não está livre... Muito pelo contrário, está a "dormir" por alguns segundos.

Isso significa que os controlos somente serão actualizados quando este bloco de código terminar a execução.

O *correcto* para fazer o que você pretende é criar uma segunda thread para ler as configurações, deixando a thread principal livre, e somente quando esta segunda thread terminar, é que você abre o formulário de Login.

A forma mais simples de fazer isso é utilizando o controlo BackgroundWorker, que se encarrega de executar o seu código em uma thread separada, e avisa quando a execução terminou... Tudo através de eventos.

Uma outra alternativa, seguindo a sua linha de pensamento no código que mostrou, seria invocar o Dispatcher explicitamente, para forçar a actualização do controlo antes da Thread "dormir"... Algo como:

LblMsg.Content =  "Inicializar os componentes..";

// Sinaliza que o label deve ser redesenhado
LblMsg.UpdateLayout();

// Solicita ao Dispatcher que execute as acções pendentes no LblMsg
LblMsg.Dispatcher.Invoke(new Action(() => { }), 
    System.Windows.Threading.DispatcherPriority.Background);

Vale lembrar que essa *não* é propriamente uma boa prática, mas é similar ao DoEvents que você estava a tentar executar.

Cumprimentos,

Caio Proiete

Link to comment
Share on other sites

E pq dizes q a tua segunda solução não é uma boa prática?

Boas,

Porque a aplicação continua "congelada" na mesma, e o utilizador não pode interagir com a aplicação enquanto o bloco de código estiver a ser executado. A única diferença é que agora o texto do Label aparece...

Em termos de experiência de utilizador, é como se ainda estivéssemos em 1998  😉

Cumprimentos,

Caio Proiete

Link to comment
Share on other sites

A utilização do BeginInvoke em vez do Invoke seria uma solução?

Também não... O BeginInvoke não cria uma nova thread... Ele apenas coloca o delegate na fila do Dispatcher, para ser executado de forma assíncrona, mas ainda acontece na thread principal (que está ocupada/a dormir).

A solução *correcta*, como eu disse abaixo, é criar uma nova thread para executar o processamento, e deixar a thread da interface gráfica livre para que o utilizador possa interagir.

Cumprimentos,

Caio Proiete

Link to comment
Share on other sites

Boas,

mas diz-me uma coisa sempre que pretendo alterar o conteudo da minha Label tinha que criar um  Dispatcher?

Não. O Dispatcher é para quando uma thread está a tentar modificar recursos (neste caso o conteúdo da label) da thread principal. Se for na thread que é dona do recurso não precisas de usar o Dispatcher.

"Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !"

Sign on a computer system consultant's desk

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.