Usuário com melhor resposta
Winforms Mdi MdiChild Modal

Pergunta
-
Respostas
-
Olá Ricardo,
A solução mais comum para esse tipo de problema, é guardar uma referência para o formulário a ser instanciado em uma variável da sua classe, que você pode utilizar para controlar se já existe ou não uma instância. Algo como:
// Variável da classe que guarda a referência para // o formulário aberto (se estiver, caso contrário, null) private FormFilho formFilho; private void MenuItem_Click(object sender, RoutedEventArgs e) { // O formulário já está aberto? if (this.formFilho != null) { // Sim. Então apenas deixe-o ativo (foco) this.formFilho.Activate(); } else { // Não. Então vamos abrir e guardar a referência this.formFilho = new FormFilho(); // Vamos reinicializar a variável quando o formulário for fechado this.formFilho.Closed += delegate { this.formFilho = null; }; // Mostra o formulário this.formFilho.Show(); } }
Outra solução muito parecida, é desabilitar o botão (ou item de menu) que abre o formulário, e só voltar a habilitá-lo quando o formulário fechar... Algo mais ou menos assim:
// Desabilita o botão (ou item de menu) que abre este formulário this.botaoQueAbreEsteForm.Enabled = false; // Instancia o formulário como sendo "filho" do MDI var f = new FormFilho(); f.MdiParent = this; // Volta a habilitar o item de menu apenas quando o formulário fechar f.Closed += delegate { this.botaoQueAbreEsteForm.Enabled = true; }; // Mostra o formulário f.Show();
Por fim, se o formulário puder ser aberto de diferentes lugares, e desabilitar todos os botões/itens de menu ficar complicado, então acredito que a sugestão do Robson seja a ideal, procurando pelo formulário na lista de formulários instanciados, para decidir se deve ou não criar uma nova instância...
Nesse caso, e apenas para complementar, pode economizar algumas linhas de código utilizando uma query LINQ para procurar o formulário... O resultado é o mesmo:
// Procura o formulário na lista de formulários filhos instanciados var f = this.MdiChildren.OfType<FormFilho>().FirstOrDefault(); // Não encontrou? if (f == null) { // Não... Então cria a instância e mostra. f = new FormFilho(); f.MdiParent = this; f.Show(); return; } // Se chegou até aqui, é porque o formulário já existia... // Sim. Então apenas deixe-o ativo (foco) f.Focus();
Por fim, se você tem uma quantidade muito grande de formulários em sua aplicação, que só devem ter uma instância aberta de cada vez, pode considerar a criação de uma classe só para isso (FormLoader)... Verificar, instanciar e mostrar formulários. Dê uma olhada no exemplo do Roy Osherove:
Problem & Solution: Allow only one instance of any MDI child form in your MDI application
http://weblogs.asp.net/rosherove/archive/2004/06/16/156933.aspx
Abraços,
Caio Proiete
Caio Proiete
Microsoft MVP, MCT, MCPD, MCTS, MCSD
http://www.caioproiete.com- Sugerido como Resposta C. Augusto Proiete [MVP]Moderator terça-feira, 2 de fevereiro de 2010 16:20
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 3 de dezembro de 2010 21:10
-
Ricardo,
Não sei se existe forma mais simples de se fazer mas pode ser assim: no form pai, no item de menu que chama o form filho, coloque o codigo abaixo.
FrmTeste frmTeste = null; // form a ser aberto
// procura form na relacao de forms filhos
foreach(Form frm in this.MdiChildren)
{
// se encontrou inicializa instancia de frmTeste com o form ja aberto
if (frm is FrmTeste)
{
frmTeste = (FrmTeste)frm;
break;
}
}
// se nao encontrou na relacao, instancia objeto, "seta" form pai e exibe form
if (frmTeste == null)
{
frmTeste = new FrmTeste();
frmTeste.MdiParent = this;
frmTeste.Show();
}
// garante que ele fique em foco caso haja outros forms abertos
frmTeste.Focus();
----------
[]s
Robson Castilho - MCTS .Net 2.0 Windows/Web Applications [Se o post foi útil, não esqueça de marcá-lo. Obrigado]- Sugerido como Resposta Ari C. RaimundoModerator sábado, 4 de julho de 2009 17:59
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 3 de dezembro de 2010 21:10
Todas as Respostas
-
Da uma olhada aqui
http://social.msdn.microsoft.com/Forums/pt-BR/clientept/thread/869b8084-8cc8-4620-ac3a-57af6eebaf70
Agora ter um Filho modal nunca tentei... mesmo pq nao faz muito sentido... pq o Modal teria q ficar sobre o Pai...
Se não funciona de um jeito, tente de outro totalmente diferente ^_^ -
Rui, o formulário já está sendo chamado e mostrado dentro do formulário mdi, acontece é que cada vez que eu clico é criada uma nova instancia desse formulário, o que eu quero é que se não existe uma instancia desse formulário ele cria, senão mostra a instancia já criada.
Att,
Ricardo
Ricardo Novais -
Ricardo,
Não sei se existe forma mais simples de se fazer mas pode ser assim: no form pai, no item de menu que chama o form filho, coloque o codigo abaixo.
FrmTeste frmTeste = null; // form a ser aberto
// procura form na relacao de forms filhos
foreach(Form frm in this.MdiChildren)
{
// se encontrou inicializa instancia de frmTeste com o form ja aberto
if (frm is FrmTeste)
{
frmTeste = (FrmTeste)frm;
break;
}
}
// se nao encontrou na relacao, instancia objeto, "seta" form pai e exibe form
if (frmTeste == null)
{
frmTeste = new FrmTeste();
frmTeste.MdiParent = this;
frmTeste.Show();
}
// garante que ele fique em foco caso haja outros forms abertos
frmTeste.Focus();
----------
[]s
Robson Castilho - MCTS .Net 2.0 Windows/Web Applications [Se o post foi útil, não esqueça de marcá-lo. Obrigado]- Sugerido como Resposta Ari C. RaimundoModerator sábado, 4 de julho de 2009 17:59
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 3 de dezembro de 2010 21:10
-
Olá Ricardo,
A solução mais comum para esse tipo de problema, é guardar uma referência para o formulário a ser instanciado em uma variável da sua classe, que você pode utilizar para controlar se já existe ou não uma instância. Algo como:
// Variável da classe que guarda a referência para // o formulário aberto (se estiver, caso contrário, null) private FormFilho formFilho; private void MenuItem_Click(object sender, RoutedEventArgs e) { // O formulário já está aberto? if (this.formFilho != null) { // Sim. Então apenas deixe-o ativo (foco) this.formFilho.Activate(); } else { // Não. Então vamos abrir e guardar a referência this.formFilho = new FormFilho(); // Vamos reinicializar a variável quando o formulário for fechado this.formFilho.Closed += delegate { this.formFilho = null; }; // Mostra o formulário this.formFilho.Show(); } }
Outra solução muito parecida, é desabilitar o botão (ou item de menu) que abre o formulário, e só voltar a habilitá-lo quando o formulário fechar... Algo mais ou menos assim:
// Desabilita o botão (ou item de menu) que abre este formulário this.botaoQueAbreEsteForm.Enabled = false; // Instancia o formulário como sendo "filho" do MDI var f = new FormFilho(); f.MdiParent = this; // Volta a habilitar o item de menu apenas quando o formulário fechar f.Closed += delegate { this.botaoQueAbreEsteForm.Enabled = true; }; // Mostra o formulário f.Show();
Por fim, se o formulário puder ser aberto de diferentes lugares, e desabilitar todos os botões/itens de menu ficar complicado, então acredito que a sugestão do Robson seja a ideal, procurando pelo formulário na lista de formulários instanciados, para decidir se deve ou não criar uma nova instância...
Nesse caso, e apenas para complementar, pode economizar algumas linhas de código utilizando uma query LINQ para procurar o formulário... O resultado é o mesmo:
// Procura o formulário na lista de formulários filhos instanciados var f = this.MdiChildren.OfType<FormFilho>().FirstOrDefault(); // Não encontrou? if (f == null) { // Não... Então cria a instância e mostra. f = new FormFilho(); f.MdiParent = this; f.Show(); return; } // Se chegou até aqui, é porque o formulário já existia... // Sim. Então apenas deixe-o ativo (foco) f.Focus();
Por fim, se você tem uma quantidade muito grande de formulários em sua aplicação, que só devem ter uma instância aberta de cada vez, pode considerar a criação de uma classe só para isso (FormLoader)... Verificar, instanciar e mostrar formulários. Dê uma olhada no exemplo do Roy Osherove:
Problem & Solution: Allow only one instance of any MDI child form in your MDI application
http://weblogs.asp.net/rosherove/archive/2004/06/16/156933.aspx
Abraços,
Caio Proiete
Caio Proiete
Microsoft MVP, MCT, MCPD, MCTS, MCSD
http://www.caioproiete.com- Sugerido como Resposta C. Augusto Proiete [MVP]Moderator terça-feira, 2 de fevereiro de 2010 16:20
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 3 de dezembro de 2010 21:10