如何在设计时从 WPF 应用程序获取应用程序的目录?
如何在设计时从 WPF 应用程序获取应用程序的目录? 我需要在设计时访问应用程序当前目录中的资源,同时我的 XAML 显示在设计器中。我无法使用此问题 在设计时,System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
和 System.Reflection.Assembly.GetExecutingAssembly().Location
指向 IDE 的位置(Visual Studio...Common7 或其他)。
根据要求进一步明确我的目标:我想在设计时访问数据库表并显示该数据的图形。该设计是在 Visual Studio 2008 中完成的,因此我需要的是针对一个非常具体的问题的非常具体的解决方案,那就是获取我的应用程序的程序集目录。
How do I get the application's directory from my WPF application, at design time? I need to access a resource in my application's current directory at design time, while my XAML is being displayed in the designer. I'm not able to use the solution specified in this question as at design time both System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
and System.Reflection.Assembly.GetExecutingAssembly().Location
point to the IDE's location (Visual Studio... Common7 or something).
Upon request to further clarify my goals: I want to access a database table at design time and display a graphic of that data. The design is done in Visual Studio 2008, so what I need is a very specific solution to a very specific problem, and that is getting the assembly directory for my app.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从您的描述来看,您的代码实际上是在 Visual Studio 内的 WPF 设计器内运行,例如,它是用于设计的自定义控件库的一部分。
在本例中,
Assembly.GetEntryAssembly()
返回 null,但以下代码获取应用程序目录的路径:可以使用以下步骤来演示在 VS.NET 2008 的 WPF Designer 工具中的工作原理:
当您按照这些步骤操作时,您正在查看的对象将填充来自您的数据数据库在运行时和设计时都以相同的方式。
在其他场景中,相同的技术也能发挥同样的作用,并且根据您的需求,还有其他可用的解决方案。如果您的需求与我上面假设的不同,请告诉我们。例如,如果您正在编写 VS.NET 插件,那么您将面临完全不同的游戏。
From your description it sounds like your code is actually running inside the WPF Designer within Visual Studio, for example it is part of a custom control library that is being used for design.
In this case,
Assembly.GetEntryAssembly()
returns null, but the following code gets the path to the application directory:The following steps can be used to demonstrate this works inside VS.NET 2008's WPF Designer tool:
When you follow these steps, the object you are looking at will be populated with data from your database the same way both at run time and design time.
There are other scenarios in which this same technique works just as well, and there are other solutions available depending on your needs. Please let us know if your needs are different those I assumed above. For example, if you are writing a VS.NET add-in, you are in a completely different ball game.
您是否想支持设计师(例如视觉工作室设计师或 Blend)?
如果是这样,那么有多种不同的方法来解决这个问题。您通常不想依赖可执行文件的相对路径,因为它可以托管在各种不同的设计工具(VS、Expression Blend 等)中。
也许您可以更全面地解释您要解决的问题,以便我们可以提供更好的答案?
Are you trying to support a designer (such as the visual studio designer or Blend)?
If so then there are various different ways to approach this problem. You typically don't want to rely a relative path from executable because it can be hosted in various different design tools (VS, Expression Blend etc..)
Maybe you can more fully explain the problem you are trying to solve so we can provide a better answer?
我认为这是不可能的 - 您正在询问可能尚未构建的程序集的位置。您的设计时代码不会在应用程序内部运行,并且必须对 IDE 做出一些假设。这对我来说是错误和脆弱的 - 考虑这些问题:
在这种情况下,您可能应该在设计时要求用户通过在对象上添加属性供他们编辑来提供或浏览路径。然后,您的设计时代码可以使用该属性的值来查找它需要的内容。
I don't think this is possible - you're asking for the location of an assembly that potentially hasn't even been built yet. Your design-time code does not run inside your application and would have to make some assumptions about the IDE. This feels wrong and brittle to me - consider these questions:
In this situation you should probably ask the user, at design time, to provide or browse for a path by adding a property on your object for them to edit. Your design time code can then use the value of the property to find what it needs.
如果您广泛使用装饰器等进行 WPF 设计器工作,请使用“Context”属性/类型
详细信息:-
在设计时,您有 modelItem 的实例(我假设它,您知道)如果没有,那么您可以在
DesignAdorner 类中的Activate 方法的 Override 实现 //
中实例化它现在您可以使用以下单行代码访问当前应用程序路径
让我知道,如果这对你没有帮助。
If you are extensively working on WPF designers using adorner etc, please use "Context" property/type
Details:-
In Design time you have instance of modelItem (I assume it, you know it) if not then you can instantiate it in Override implementation of Activate method
// in DesignAdorner class
Now you can access the current application path using following single line code
Let me know, if it does not help you.
好的,鉴于这里的进一步说明,这就是我要做的。
与 GraemeF 提出的担忧一致,做你想做的事情是脆弱的,充其量也容易崩溃。
因此,一般做法是将设计时数据支持视为与运行时数据支持完全不同的方法。很简单,您在设计时环境和该数据库之间创建的耦合是一个坏主意。
为了简单地提供用于可视化的设计时数据,我更喜欢使用遵循公共接口的模拟类作为运行时类。这为我提供了一种显示数据的方法,我可以确保这些数据具有正确的类型并且符合与运行时对象相同的约定。然而,这是一个完全不同的类,用于设计时支持(并且通常用于单元测试)。
例如。如果我有一个运行时类需要显示人员详细信息,例如名字、姓氏和电子邮件:
并且我在运行时从数据库填充此对象,但还需要提供设计时可视化,我将引入一个 IPerson 接口定义要遵守的契约,即强制属性 getter 存在:
然后我将更新运行时 Person 类以实现该接口:
然后我将创建一个模拟类,该类实现相同的接口并为设计时使用提供合理的值
然后我将实现一种机制,在设计时提供 MockPerson 对象,在运行时提供真实的 Person 对象。像 这个 或这个。这提供了设计时数据支持,而无需运行时和设计时环境之间的硬依赖。
这种模式更加灵活,允许您在整个应用程序中提供一致的设计时数据支持。
Ok given the further clarification here is what I would do.
staying in line with the concern raised by GraemeF, doing what you want is brittle and prone to breaking at best.
Because of this the general practice is to treat design time data support as a wholly different approach then runtime data support. Very simply, the coupling you are creating between your design time environment and this DB is a bad idea.
To simply provide design time data for visualization I prefer to use a mock class that adheres to a common Interface as the runtime class. This gives me a way to show data that I can ensure is of the right type and conforms to the same contract as my runtime object. Yet, this is a wholly different class that is used for design time support (and often used for Unit Testing).
So for example. If I had a run time class that needs to show person details such as first name, last name and Email:
and I was populating this object from a DB at runtime but also need to provide a design time visualization I would introduce an IPerson interface that defines the contract to adhere to, namely enforces that the property getters exist:
Then I would update my runtime Person class to implement the interface:
Then I would create a mock class that implements the same interface and provides sensible values for design time use
Then I would implement a mechanism to provide the MockPerson object at design time and the real Person object at runtime. Something like this or this. This provides design time data support without the hard dependency between the runtime and design time environments.
This pattern is much more flexible and will allow you to provide consistent design time data support throughout your application.