Alguém encontrou uma solução útil para o problema DesignMode ao desenvolver controles?
O problema é que, se você aninhar os controles, o DesignMode funcionará apenas para o primeiro nível. O segundo DesignMode e os níveis inferiores sempre retornarão FALSE.
O hack padrão tem sido olhar para o nome do processo que está sendo executado e se for "DevEnv.EXE", então deve ser studio, portanto, DesignMode é realmente TRUE.
O problema com isso é procurar pelo ProcessName percorrer todo o registro e outras partes estranhas com o resultado final de que o usuário pode não ter os direitos necessários para ver o nome do processo. Além disso, esta estranha rota é muito lenta. Portanto, tivemos que empilhar hacks adicionais para usar um singleton e, se um erro for lançado ao solicitar o nome do processo, suponha que DesignMode seja FALSE.
Uma boa maneira limpa de determinar DesignMode está em ordem. Fazer a Microsoft consertá-lo internamente na estrutura seria ainda melhor!
fonte
Respostas:
Revendo esta questão, agora 'descobri' 5 maneiras diferentes de fazer isso, que são as seguintes:
Para tentar segurar as três soluções propostas, criei uma pequena solução de teste - com três projetos:
Em seguida, incorporei o SubSubControl no SubControl e, em seguida, um de cada no TestApp.Form.
Esta imagem mostra o resultado durante a execução.
Esta captura de tela mostra o resultado com o formulário aberto no Visual Studio:
Conclusão: Parece que, sem reflexão, o único que é confiável dentro do construtor é LicenseUsage, e o único que é confiável fora do construtor é 'IsDesignedHosted' (por BlueRaja abaixo)
PS: Veja o comentário de ToolmakerSteve abaixo (que não testei): "Observe que a resposta IsDesignerHosted foi atualizada para incluir LicenseUsage ..., então agora o teste pode ser simplesmente if (IsDesignerHosted). Uma abordagem alternativa é testar LicenseManager no construtor e armazenar em cache o resultado . "
fonte
if(LicenseUseage == LicenseUsageMode.Designtime || IsDesignerHosted)
seria a abordagem 100% correta?LicenseUsage...
, então agora o teste pode simplesmente serif (IsDesignerHosted)
. Uma abordagem alternativa é testar o LicenseManager no construtor e armazenar em cache o resultado .A partir desta página :
( [Editar 2013] Editado para trabalhar em construtores, usando o método fornecido por @hopla)
Enviei um relatório de bug com a Microsoft; Eu duvido que vá a qualquer lugar, mas vote mesmo assim, pois isso é obviamente um bug (seja ou não "por design" ).
fonte
Por que você não verifica LicenseManager.UsageMode. Essa propriedade pode ter os valores LicenseUsageMode.Runtime ou LicenseUsageMode.Designtime.
Se você deseja que o código seja executado apenas em tempo de execução, use o seguinte código:
fonte
Este é o método que uso nos formulários:
Dessa forma, o resultado será correto, mesmo se uma das propriedades DesignMode ou LicenseManager falhar.
fonte
Eu uso o método LicenseManager, mas armazeno em cache o valor do construtor para uso durante a vida útil da instância.
Versão VB:
fonte
Usamos este código com sucesso:
fonte
Minha sugestão é uma otimização de @ blueraja-danny pflughoeft resposta . Esta solução não calcula o resultado todas as vezes, mas apenas na primeira vez (um objeto não pode alterar o UsageMode do design para o tempo de execução)
fonte
Eu nunca fui pego por isso, mas você não poderia simplesmente caminhar de volta para cima na cadeia Parent do controle para ver se DesignMode está definido em algum lugar acima de você?
fonte
Como nenhum dos métodos é confiável (DesignMode, LicenseManager) ou eficiente (Processo, verificações recursivas), estou usando um
public static bool Runtime { get; private set }
no nível do programa e configurando-o explicitamente dentro do método Main ().fonte
DesignMode é uma propriedade privada (pelo que posso dizer). A resposta é fornecer uma propriedade pública que expõe a propriedade DesignMode. Em seguida, você pode cascasde backup da cadeia de controles de usuário até que você encontre um controle não-usuário ou um controle que está no modo de design. Algo assim....
Onde todos os seus UserControls herdam de MyBaseUserControl. Alternativamente, você pode implementar uma interface que expõe o "RealDeisgnMode".
Observe que este código não é um código ao vivo, apenas de improviso. :)
fonte
Eu não tinha percebido que você não pode chamar Parent.DesignMode (e também aprendi algo sobre 'protegido' em C # ...)
Aqui está uma versão reflexiva: (eu suspeito que pode haver uma vantagem de desempenho em tornar designModeProperty um campo estático)
fonte
Tive que lutar contra esse problema recentemente no Visual Studio 2017 ao usar UserControls aninhados. Eu combino várias das abordagens mencionadas acima e em outros lugares, então ajustei o código até que eu tivesse um método de extensão decente que funcionasse de forma aceitável até agora. Ele executa uma sequência de verificações, armazenando o resultado em variáveis booleanas estáticas de forma que cada verificação seja realizada no máximo uma vez em tempo de execução. O processo pode ser exagerado, mas está impedindo a execução do código no estúdio. Espero que isso ajude alguém.
fonte