在单独的项目中定义WPF资源时避免Visual Studio设计器错误
在单独的项目中定义WPF资源时,如何避免Visual Studio designer错误 我在复合WPF应用程序中有三个项目:主应用程序、一个“基础结构”库和一个“模块”库。主应用程序通过它们的输出DLL引用其他项目(这些项目不在同一个解决方案中) 我正在“infrastructure”库中定义一个皮肤(在在单独的项目中定义WPF资源时避免Visual Studio设计器错误,wpf,visual-studio-2008,xaml,skinning,pack-uri,Wpf,Visual Studio 2008,Xaml,Skinning,Pack Uri,在单独的项目中定义WPF资源时,如何避免Visual Studio designer错误 我在复合WPF应用程序中有三个项目:主应用程序、一个“基础结构”库和一个“模块”库。主应用程序通过它们的输出DLL引用其他项目(这些项目不在同一个解决方案中) 我正在“infrastructure”库中定义一个皮肤(在ResourceDictionary中有一些笔刷和样式)。我希望主应用程序选择一个皮肤并使其可用于整个应用程序(通过App.xaml中的MergedDictionaries) 在我的模块中,我
ResourceDictionary
中有一些笔刷和样式)。我希望主应用程序选择一个皮肤并使其可用于整个应用程序(通过App.xaml中的MergedDictionaries
)
在我的模块中,我想使用在主应用程序加载的皮肤中定义的资源。如果我引用资源,就好像它在本地可用一样,如下所示:
Background={StaticResource MainBackgroundBrush}
几乎所有东西都能按预期工作。唯一的例外是VisualStudio的设计师感到困惑,并告诉我“找不到StaticResource引用‘MainBackgroundBrush’”。这有效地阻止了我使用设计器
如何在项目中定义“皮肤”
ResourceDictionary
,在主应用程序中引用该皮肤,然后在模块项目中使用其资源?一种可能的解决方案是使用DynamicSource
而不是StaticResource
。VisualStudio2008设计器只显示控件而不显示任何样式,就像VS2010 beta 1无法解析静态资源时所做的那样
使用DynamicResource
适用于特定样式可能在运行时发生更改的情况,例如蒙皮时
我发现一些相关问题支持这一点:
我还发现有人说,只要资源不是本地的,就应该使用DynamicResource
:
您可以创建自己的ResourceDictionary类,继承自ResourceDictionary。
然后,您可以安排此自定义ResourceDictionary在设计时加载一些明确定义的样式(即在运行时从应用程序加载的样式),而在运行时它什么也不做。
可以为此计算IsInDesignMode属性
假设您有一个名为“DesignTimeResourceDictionary”的类,那么您只需使用s.th。像
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<Util:DesignTimeResourceDictionary Source="SomeUriToYourResources"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
在设计时加载资源并使设计器正常工作。
在运行时,您可以使DesignTimeResourceDictionary跳过资源的加载,并实现所需的行为
如果需要,您可以为此创建一个真实资源的副本,也可以创建一个虚拟字典,其中包含保持设计器正常工作所需的所有键 我只想扩展Simon D.答案。他提出的是我现在正在使用的解决方案。我只是想分享完整的源代码。它来自这个来源
公共类DesignTimeResourceDictionary:ResourceDictionary
{
///
///存储有关设计时间源信息的本地字段。
///
私有字符串设计时间源;
///
///获取或设置设计时源。
///
///
///设计时间源。
///
公共字符串设计时间源
{
得到
{
返回此.designTimeSource;
}
设置
{
this.designTimeSource=值;
if((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
{
base.Source=新Uri(designTimeSource);
}
}
}
///
///获取或设置从中加载资源的统一资源标识符(URI)。
///
///外部资源字典的源位置。
公共新Uri源
{
得到
{
抛出新异常(“使用DesignTimeSource代替Source!”);
}
设置
{
抛出新异常(“使用DesignTimeSource代替Source!”);
}
}
}
点击我
虽然这在技术上根本不能回答您的问题,但Expression Blend 2在双重间接查找方面没有问题,根据我的经验,在这些特定情况下,只需查找即可。在VS2010 Beta 1中,如果找不到资源,您仍然可以使用设计器。它给你一个警告,然后似乎忽略了属性。为我(几乎)完美地解决了它。它引起的唯一问题是窗口元素的样式问题,但我认为这是设计师使用“WindowInstance”类而不是实际的“window”类的问题。至少我现在可以在设计时看到我的风格了!
public class DesignTimeResourceDictionary : ResourceDictionary
{
/// <summary>
/// Local field storing info about designtime source.
/// </summary>
private string designTimeSource;
/// <summary>
/// Gets or sets the design time source.
/// </summary>
/// <value>
/// The design time source.
/// </value>
public string DesignTimeSource
{
get
{
return this.designTimeSource;
}
set
{
this.designTimeSource = value;
if ((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
{
base.Source = new Uri(designTimeSource);
}
}
}
/// <summary>
/// Gets or sets the uniform resource identifier (URI) to load resources from.
/// </summary>
/// <returns>The source location of an external resource dictionary. </returns>
public new Uri Source
{
get
{
throw new Exception("Use DesignTimeSource instead Source!");
}
set
{
throw new Exception("Use DesignTimeSource instead Source!");
}
}
}
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation Jump "
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml Jump "
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfApplication1">
<Window.Resources>
<local:DesignTimeResourceDictionary DesignTimeSource="pack://application:,,,/BlueColors.xaml"/>
</Window.Resources>
<Grid>
<Button Background="{DynamicResource defaultBackground}"
HorizontalAlignment="Center" VerticalAlignment="Center">click me</Button>
</Grid>
</Window>