Como faço para obter o diretório do aplicativo do meu aplicativo WPF, em tempo de design?

StackOverflow https://stackoverflow.com/questions/1808856

Foi útil?

Solução

De sua descrição parece que o código está sendo executado dentro do Designer WPF dentro do Visual Studio, por exemplo, é parte de uma biblioteca de controle personalizado que está sendo usado para o projeto.

Neste caso, Assembly.GetEntryAssembly() retorna NULL, mas o seguinte código obtém o caminho para o diretório do aplicativo:

  string applicationDirectory = (
    from assembly in AppDomain.CurrentDomain.GetAssemblies()
    where assembly.CodeBase.EndsWith(".exe")
    select System.IO.Path.GetDirectoryName(assembly.CodeBase.Replace("file:///", ""))
    ).FirstOrDefault();

As seguintes etapas podem ser usadas para demonstrar isso funciona dentro ferramenta Designer WPF VS.NET 2008 é:

  1. Coloque este código dentro de um projeto "Biblioteca de controle WPF personalizado" ou "Biblioteca de classes"
  2. Adicione o que o código é necessário ler o banco de dados e retornar os dados para exibição (no meu caso eu só retornou o diretório do aplicativo em si como uma string)
  3. Referência do projecto de biblioteca do projeto que você está projetando
  4. Use os controles personalizados ou classes de um arquivo XAML para preencher o seu DataContext ou não fornecem dados para o UI (no meu caso eu ligado DataContext usando x: Static)
  5. Editar esse arquivo XAML com o "Windows Presentation Foundation Designer", que pode ser feito por apenas um clique duplo a menos que tenha mudado seu editor padrão, em que caso de uso "Abrir com ..."

Quando você seguir essas etapas, o objeto que você está olhando será preenchida com os dados de seu banco de dados da mesma forma tanto em tempo de execução e tempo de design.

Existem outros cenários em que essa mesma técnica funciona tão bem, e há outras soluções disponíveis, dependendo de suas necessidades. Por favor, deixe-nos saber se suas necessidades são diferentes daqueles que eu assumida acima. Por exemplo, se você estiver escrevendo um VS.NET add-in, você está em um jogo de bola completamente diferente.

Outras dicas

Você está tentando apoiar um designer (como o designer visual studio ou Mistura)?

Se sim, então existem várias maneiras diferentes de abordar este problema. Você normalmente não quer contar um caminho relativo do executável porque pode ser hospedado em várias ferramentas de design diferentes (VS, Expression Blend etc ..)

Talvez você possa explicar mais detalhadamente o problema que você está tentando resolver, para que possamos dar uma resposta melhor?

Eu não acho que isso é possível - você está pedindo para a localização de um conjunto que, potencialmente, nem sequer foi ainda construído. Seu código de tempo de design não é executado dentro de sua aplicação e teria que fazer algumas suposições sobre o IDE. Este parece errado e frágil para mim - considere estas perguntas:

  • O projecto foi construído ainda?
  • Se não, não há nenhum executável para obter o caminho, então o que então?
  • Será que os outros arquivos estar presentes, se não tiver sido construído, ou são construir artefatos?
  • Se tiver sido construído, onde ele foi construído para?
  • Você precisa considerar outros IDEs?

Nesta situação, você provavelmente deve pedir ao utilizador, em tempo de design, para fornecer ou procure um caminho através da adição de uma propriedade em seu objeto para eles edição. Seu código tempo de design pode usar o valor da propriedade para encontrar o que precisa.

Se você está extensivamente trabalhando em WPF designers usando adorno etc, utilize o "contexto" propriedade / tipo

Detalhes: - In Design vez que você tem instância de ModelItem (presumo que, você sabe que) se não, então você pode instanciá-lo na implementação Override do método Activate

// na classe DesignAdorner

public class DesignAdorner : PrimarySelectionAdornerProvider
{
      protected override void Activate(ModelItem item)
        {
                modelItem = item;
        }
}

Agora você pode acessar o caminho do aplicativo atual usando seguinte código única linha

string aplicationPathDir = System.IO.Directory.GetParent(modelItem.Context.ToString()).FullName;

Deixe-me saber, se ele não ajudá-lo.

Ok dado o esclarecimento adicional aqui é o que eu faria.

ficar em linha com a preocupação levantada por GraemeF, fazendo o que você quer é frágil e propenso a quebrar na melhor das hipóteses.

Devido a isso a prática geral é a de suporte de dados em tempo de design tratar como uma abordagem totalmente diferente de suporte de dados, em seguida, tempo de execução. Muito simplesmente, o acoplamento está a criar entre o seu ambiente de tempo de design e este DB é uma má idéia.

Para simplesmente fornecer dados em tempo de design para visualização Eu prefiro usar uma classe falsa que adere a uma interface comum como a classe de tempo de execução. Isso me dá uma maneira de mostrar os dados que eu posso garantir é do tipo certo e está em conformidade com o mesmo contrato como meu objeto de tempo de execução. No entanto, esta é uma classe totalmente diferente que é usado para suporte em tempo de design (e muitas vezes usado para Unidade de Teste).

Assim, por exemplo. Se eu tivesse uma classe tempo de execução que precisa mostrar detalhes pessoa, como nome, sobrenome e e-mail:

public class Person()
{
    public String FirstName { get; set;}
    public String LastName {get; set;}
    public Email EmailAddress {get; set;}
}

e eu estava preencher esse objeto de um DB em tempo de execução, mas também precisa fornecer uma visualização em tempo projeto que eu iria introduzir uma interface IPerson que define o contrato de aderir, ou seja, impõe que existem os getters de propriedade:

public interface IPerson()
{
    String FirstName { get; }
    String LastName { get; }
    Email EmailAddress { get; }
}

Então eu atualizar minha classe Pessoa tempo de execução para implementar a interface:

public class Person() : IPerson
{
public String FirstName { get; set;}
public String LastName {get; set;}
public Email EmailAddress {get; set;}
}

Então eu iria criar uma classe falsa que implementa a mesma interface e fornece valores sensíveis para uso tempo de design

public MockPerson() : IPerson
{
public String FirstName { get { return "John"; } }
public String LastName { get { return "Smith"; } } 
public Email EmailAddress { get { return new Email("John@smith.com"); } }
}

Então gostaria de implementar um mecanismo para fornecer o objeto MockPerson em tempo de design eo objeto pessoa real em tempo de execução. Algo como este ou este . Isso fornece suporte de dados em tempo de design sem a dependência duro entre os ambientes de tempo de execução e de design.

Este padrão é muito mais flexível e irá permitir que você para fornecer suporte de dados em tempo de design consistente em toda a sua aplicação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top