不同程序集中的应用程序级资源
此问题涉及 Visual Studio (2008) WPF 设计器明显无法处理位于 App.xaml 级别的资源的使用(如果 App.xaml 位于与视图不同的程序集中)。
为了简化问题的解释,我创建了一个测试应用程序。 该应用程序有两个程序集:View 和 Start。 View 程序集包含一个名为 Window1 的 xaml 窗口,Start 程序集包含 App.xaml 文件。 Start 程序集中的 App.xaml 文件将其 StartupUri 设置为 View 程序集中的 Window1。 这些文件都没有代码隐藏(除了标准构造函数和 InitializeComponent() 调用)。
本示例的代码如下:
App.xaml:
<Application x:Class="Start.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="pack://application:,,,/View;component/Window1.xaml"
>
<Application.Resources>
<!-- Warning Text Style -->
<Style x:Key="WarningTextStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Application.Resources>
Window1.xaml:
<Window x:Class="View.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="300"
Width="300"
>
<Grid>
<TextBlock Text="This is test text" Style="{StaticResource WarningTextStyle}" />
</Grid>
</Window>
Window1.xaml 文件包含引用应用程序级WarningTextStyle 的单个TextBlock。 该代码在运行时运行良好,因为 Window 正确找到了应用程序级资源; 然而,在设计时,设计者抱怨它找不到WarningTextStyle。
有人知道这个问题的干净且可扩展的解决方案吗?
我处理大型应用程序的标准方法是将应用程序级资源组织到资源字典文件中,然后将这些字典合并到 App.xaml 中。 为了解决上面描述的问题,我必须将这些资源字典合并到每个视图的资源中。 这看起来效率很低,如果我稍后添加另一个资源字典,那么我需要将该新字典合并到每个视图中。
灵丹妙药的解决方案将重新指导设计人员寻找应用程序级资源。 一个合理的解决方法是将应用程序级资源字典合并到每个视图中,但仅在设计时进行。 在运行时,由于效率问题,我希望避免在每个视图中合并这些字典。
我尝试在视图的代码隐藏构造函数中合并每个视图上的字典,然后将该逻辑包装在检查 DesignerProperties.GetIsInDesignMode() 方法的 if 语句中; 但是,Visual Studio 设计器不会运行视图的构造函数 - 因此这种方法似乎是失败的。
有人有更好的解决方案或解决方法吗?
This question involves the Visual Studio (2008) WPF Designer's apparent inability to handle the usage of resources located at the App.xaml level if the App.xaml is in a separate assembly from the view.
To simplify the explanation of the problem I have created a test application. This application has two assemblies: View and Start. The View assembly contains a xaml window called Window1, and the Start assembly includes the App.xaml file. The App.xaml file in the Start assembly has its StartupUri set to the Window1 in the View assembly. Neither of these files have code-behinds (aside from the standard constructors and InitializeComponent() call).
The code for this example is as follows:
App.xaml:
<Application x:Class="Start.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="pack://application:,,,/View;component/Window1.xaml"
>
<Application.Resources>
<!-- Warning Text Style -->
<Style x:Key="WarningTextStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Application.Resources>
Window1.xaml:
<Window x:Class="View.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="300"
Width="300"
>
<Grid>
<TextBlock Text="This is test text" Style="{StaticResource WarningTextStyle}" />
</Grid>
</Window>
The Window1.xaml file contains a single TextBlock that references the App-level WarningTextStyle. This code works fine at runtime because the Window properly finds the App-level resource; however, at design-time the designer complains that it cannot find the WarningTextStyle.
Does anybody know of a clean and scalable solution to this problem?
My standard approach with large applications is to organize my app-level resources into resource dictionary files, and then merge those dictionaries in the App.xaml. To work around the problem that I've described above I have to merge those resource dictionaries into each view's resources. This seems very inefficient, and if I later add another resource dictionary then I need to merge that new dictionary into every view.
A silver bullet solution would re-direct the designer to find the app-level resources. A reasonable work around would be the merging of the app-level resource dictionaries into each view, but only at design-time. At runtime I would like to avoid merging these dictionaries in every view because of the efficiency issues.
I've tried merging the dictionaries on each view in the view's code-behind constructor, and then wrapping that logic in an if statement that checks the DesignerProperties.GetIsInDesignMode() method; however, the Visual Studio designer does not run the view's constructor - so this approach appears to be a bust.
Does anybody have a better solution or work around?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您能否将主(exe)程序集的 App.xaml 中的资源字典合并到引用的程序集中(无论是 App.xaml 还是您自己的资源字典)?
Can you merge the resource dictionary in your referenced assembly (be it App.xaml or your own resource dictionary) from your main (exe) assembly's App.xaml?
我只是有一个不同的想法:使用动态资源而不是静态资源。 这可能会对性能造成微小的影响,但我怀疑这是可以衡量的。
I just had a different idea: use a DynamicResource instead of a Static one. This might introduce a tiny performance hit, but I doubt it would be measurable.