代码之家  ›  专栏  ›  技术社区  ›  sourcenouveau

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

  •  32
  • sourcenouveau  · 技术社区  · 15 年前

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

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

    我正在定义一个皮肤(在 ResourceDictionary )在“基础设施”库中。我希望主应用程序选择一个皮肤并使其可用于整个应用程序(通过 MergedDictionaries 在App.xAML中。

    在我的模块中,我希望使用在主要应用程序加载的外观中定义的资源。如果我像这样引用本地可用的资源:

    Background={StaticResource MainBackgroundBrush}
    

    几乎每件事都能按要求工作。例外情况是,Visual Studio的设计器会感到困惑,并告诉我“找不到StaticResource引用”MainBackgroundBrush“。这有效地阻止了我使用设计师。

    如何定义“皮肤” 字典资源 在项目中,在主应用程序中引用该皮肤,然后在模块项目中使用其资源?

    3 回复  |  直到 7 年前
        1
  •  4
  •   Simon D.    15 年前

    您可以创建自己的ResourceDictionary类,从ResourceDictionary继承。 然后,您可以在设计时安排这个自定义资源字典加载一些显式定义的样式(即那些在运行时从应用程序加载的样式),而在运行时它什么也不做。 无法为此计算IsInDesignMode属性。

    假设你有一个叫做“designtimeresourcedictionary”的类,那么你只需要使用s.th。喜欢

     <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <Util:DesignTimeResourceDictionary Source="SomeUriToYourResources"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
     </UserControl.Resources>
    

    在设计时加载资源并使设计器工作。 然后,在运行时,您可以使DesignTimeResourceDictionary跳过资源加载并实现所需的行为。

    如果需要,您可以为此创建实际资源的副本,也可以创建一个虚拟字典,其中包含保持设计器正常工作所需的所有键。

        2
  •  3
  •   Community CDub    8 年前

    一种可能的解决方案是 DynamicResource 而不是 StaticResource . Visual Studio 2008设计器只显示没有任何样式的控件,就像VS2010 Beta 1无法解析 静态源 .

    使用 动态资源 适用于特定样式在运行时可能发生更改的情况,例如剥皮时。

    我发现一些相关问题支持这一点:

    我还发现有人说 动态资源 当资源不是本地资源时应使用:

        3
  •  1
  •   Tomas Kosar    7 年前

    我只想延长西蒙的回答。他提出的是我现在正在使用的解决方案。我只想共享完整的源代码。就是这样 Trick To Use A ResourceDictionary Only When In Design Mode 来源。

    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>