在单独的项目中定义WPF资源时避免Visual Studio设计器错误

在单独的项目中定义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) 在我的模块中,我

在单独的项目中定义WPF资源时,如何避免Visual Studio designer错误

我在复合WPF应用程序中有三个项目:主应用程序、一个“基础结构”库和一个“模块”库。主应用程序通过它们的输出DLL引用其他项目(这些项目不在同一个解决方案中)

我正在“infrastructure”库中定义一个皮肤(在
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>