4

設計時に、WPF アプリケーションからアプリケーションのディレクトリを取得するにはどうすればよいですか? XAML がデザイナーに表示されている間に、デザイン時にアプリケーションの現在のディレクトリにあるリソースにアクセスする必要があります。この質問で指定されたソリューションを設計時に使用することも、IDE の場所 (Visual Studio... Common7 など)System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)を指すこともできません。System.Reflection.Assembly.GetExecutingAssembly().Location

私の目標をさらに明確にする要求に応じて、設計時にデータベース テーブルにアクセスし、そのデータのグラフィックを表示したいと考えています。設計は Visual Studio 2008 で行われるため、必要なのは非常に特定の問題に対する非常に特定のソリューションであり、それはアプリのアセンブリ ディレクトリを取得することです。

4

5 に答える 5

6

あなたの説明から、コードが実際に Visual Studio 内の WPF デザイナー内で実行されているように聞こえます。たとえば、デザインに使用されているカスタム コントロール ライブラリの一部です。

この場合、Assembly.GetEntryAssembly()null を返しますが、次のコードはアプリケーション ディレクトリへのパスを取得します。

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

次の手順を使用して、これが VS.NET 2008 の WPF デザイナー ツール内で機能することを実証できます。

  1. このコードを「WPF カスタム コントロール ライブラリ」または「クラス ライブラリ」プロジェクト内に配置します。
  2. データベースを読み取り、表示するデータを返すために必要なコードを追加します (私の場合は、アプリケーション ディレクトリ自体を文字列として返しただけです)。
  3. 設計中のプロジェクトからライブラリ プロジェクトを参照する
  4. XAML ファイルのカスタム コントロールまたはクラスを使用して、DataContext にデータを設定するか、UI にデータを提供します (私の場合は、x:Static を使用して DataContext をバインドしました)。
  5. その XAML ファイルを「Windows Presentation Foundation Designer」で編集します。これは、デフォルトのエディターを変更していない限り、ダブルクリックするだけで実行できます。その場合は、「Open With...」を使用します。

これらの手順に従うと、参照しているオブジェクトには、実行時と設計時の両方で同じ方法でデータベースからのデータが取り込まれます。

これと同じ手法がうまく機能する他のシナリオがあり、ニーズに応じて他のソリューションを利用できます。あなたのニーズが上記で想定したものと異なる場合はお知らせください。たとえば、VS.NET アドインを作成している場合は、まったく別のボール ゲームに参加しています。

于 2010-01-21T07:21:37.630 に答える
0

デザイナー (ビジュアル スタジオ デザイナーや Blend など) をサポートしようとしていますか?

もしそうなら、この問題にアプローチするにはさまざまな方法があります。さまざまな設計ツール (VS、Expression Blend など) でホストできるため、通常、実行可能ファイルからの相対パスに依存する必要はありません。

解決しようとしている問題をより完全に説明していただければ、より良い回答を提供できますか?

于 2009-11-27T19:30:57.763 に答える
0

これは不可能だと思います - まだビルドされていない可能性のあるアセンブリの場所を求めています。設計時のコードはアプリケーション内で実行されないため、IDE についていくつかの仮定を行う必要があります。これは私には間違っていて脆く感じます - これらの質問を考えてみましょう:

  • プロジェクトはまだ構築されていますか?
  • そうでない場合は、パスを取得する実行可能ファイルがありません。
  • ビルドされていない場合、他のファイルは存在しますか、それともビルドアーティファクトですか?
  • 建てられた場合、どこに建てられましたか?
  • 他の IDE を検討する必要がありますか?

このような状況では、設計時に、ユーザーが編集できるようにオブジェクトにプロパティを追加して、パスを提供または参照するようにユーザーに依頼する必要があります。設計時のコードは、プロパティの値を使用して、必要なものを見つけることができます。

于 2009-11-27T13:50:59.070 に答える
-2

ここでさらに明確にすると、私が行うことです。

GraemeFによって提起された懸念に沿ったままで、あなたが望むことをすることはもろく、せいぜい壊れやすいです。

このため、一般的な方法は、設計時のデータサポートを実行時のデータサポートとはまったく異なるアプローチとして扱うことです。非常に簡単に言えば、設計時環境とこのDBの間に作成している結合は悪い考えです。

視覚化のための設計時データを単純に提供するために、ランタイムクラスとして共通のインターフェイスに準拠するモッククラスを使用することを好みます。これにより、正しいタイプであり、ランタイムオブジェクトと同じコントラクトに準拠していることを確認できるデータを表示する方法が得られます。ただし、これはまったく異なるクラスであり、設計時のサポートに使用されます(また、多くの場合、単体テストに使用されます)。

たとえば、名、名前、電子メールなどの個人の詳細を表示する必要があるランタイムクラスがある場合:

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

実行時にDBからこのオブジェクトにデータを入力していましたが、設計時の視覚化も提供する必要があります。準拠するコントラクトを定義するIPersonインターフェイスを導入します。つまり、プロパティゲッターが存在することを強制します。

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

次に、ランタイムのPersonクラスを更新して、インターフェイスを実装します。

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

次に、同じインターフェイスを実装し、設計時に使用するための適切な値を提供するモッククラスを作成します

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"); } }
}

次に、設計時にMockPersonオブジェクトを提供し、実行時に実際のPersonオブジェクトを提供するメカニズムを実装します。このようなものまたはこれ。これにより、ランタイム環境と設計時環境の間に強い依存関係がなく、設計時データのサポートが提供されます。

このパターンははるかに柔軟性があり、アプリケーション全体で一貫した設計時のデータサポートを提供できます。

于 2010-01-21T05:30:48.940 に答える