如何在每个XAML文件中没有合并的ResourceDictionary的Blend / VS中获得WYSIWYG设计?

时间:2009-06-15 08:55:31

标签: wpf expression-blend

我刚刚为我删除了一个大内存问题,我曾经在每个xaml文件中合并我们的“Themes”资源字典,而不是仅仅在app.cs.xaml中。

然而,在删除除App.cs.xaml之外的每个文件中的合并之后,我丢失了设计时间样式/模板。

请注意:这仅适用于合并到我们的Themes.xaml中的样式(例如Color.xaml,Brushes.xaml - 我们为每种类型的样式都有一个)。直接在Themes.xaml(我们没有..)中定义的东西有效。

我看到两个解决方案,

1)在XAML中注释掉合并,当我想使用这些设计时,只需取消注释。

2)在每个控件的默认ctor中都有这个:(也许只适用于Blend)

#if DEBUG
Resources.MergedDictionaries.Add(
                new ResourceDictionary()
                {
                    Source = new System.Uri(@"RD.xml")
                }
                );
#endif

必须有更好的方法来设计页面和控件的设计时间,任何人都知道吗?

谢谢!

6 个答案:

答案 0 :(得分:10)

Blend 4支持Visual Studio 2010也支持的“设计时资源”。请参阅http://adamkinney.wordpress.com/2010/05/04/design-time-resources-in-expression-blend-4-rc/

它几乎只是一个包含你喜欢的MergedDictionaries的ResourceDictionary,并在项目文件中显示如下(由Blend自动添加):

<Page Include="Properties\DesignTimeResources.xaml" Condition="'$(DesignTime)'=='true' OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') AND '$(BuildingInsideVisualStudio)'!='true' AND '$(BuildingInsideExpressionBlend)'!='true')">
  <Generator>MSBuild:Compile</Generator>
  <SubType>Designer</SubType>
  <ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>

效果很好。

答案 1 :(得分:8)

我所做的是添加一个继承自ResourceDictionary的类,并覆盖source属性以检查IsInDesignMode是否为true。

如果是我设置了源代码,否则我将源保留为空白(有效阻止字典在运行时合并)

public class BlendMergedDictionary : ResourceDictionary
{
    public bool IsInDesignMode
    {
        get
        {
            return (bool)DependencyPropertyDescriptor.FromProperty(
                            DesignerProperties.IsInDesignModeProperty,
                            typeof(DependencyObject)
                            ).Metadata.DefaultValue;
        }
    }

    public new Uri Source
    {
        get { return base.Source; }
        set
        {
            if (!IsInDesignMode)
                return;

            Debug.WriteLine("Setting Source = " + value);
            base.Source = value;
        }
    }
}

现在,当我需要在Blend中引用字典时,我会像这样在字典中合并

<ResourceDictionary.MergedDictionaries>
            <BlendHelpers:BlendMergedDictionary Source="Foo.xaml" />
</ResourceDictionary.MergedDictionaries>

您仍然必须在每个文件的字典中“合并”,但是您不需要支付在运行时实际加载字典的代价。合并仅用于支持设计时行为。

答案 2 :(得分:1)

Janes的问题实际上与这个有关,我有同样的问题。我已经像Foovanadil建议的那样创建了ResourceDictionary的子类,但是在设计时这会抛出“Uri前缀未重新编码”异常

即使所有子类都分配了ResourceDictionary的base.Source属性,我也会收到此错误。如果我用常规的ResourceDictionary替换我的自定义ResourceDictionary,它工作得很好,所以我猜测苹果酒设计师做了一些特别的事情,或许用其他东西替换ResourceDictionary

我没有在混合中尝试这个,但我确实在VS2010(sp1 beta)中得到了它 有人可以确认发布的awnser在vs2010中有效吗?

<强> -edit -

基于wpf的设计者可能会使资源定位逻辑瘫痪。包含uris的I've read elsewhere基于-executing- assembly,而不是neccecarily -local-assembly。我会报告我发现的什么

<强> -edit2 /溶液 -

好吧,所以我设法让Foovanadil解决方案在VS2010中工作,这是交易。事实证明我是对的,可能是因为VS2010中的wpf设计器本身是用wpf编写的,或者为了提供更好的设计体验,ResourceDictionary(或VS2010使用的其他类)在设计时表现得非常差。

事实证明,VS取代了在xaml中输入的URI。加入VS实例并在Source的setter中设置断点,可以发现实际传递的值与我们预期的不同。

鉴于xaml:

<Window.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <local:DesignTimeResourceDictionary Source="myxamlfile.xaml"  />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Window.Resources>

Source设置为

markup://1/file:///c:/PathtoMyapp/MainWindow.xaml#0/myxamlfile.xaml

而不是

/myxamlfile.xaml

这就是为什么我们得到无效uris的例外。

VS2010在设计时以这种方式编辑URI的确切时间和地点我不知道,但它将Source中的DesignTimeResourceDictionary属性重命名为其他内容并不能解决问题

Luckliy有一个解决方法。如果我们将Source的类型从Uri更改为String,则VS设计人员不会修改该值。然后在setter中创建一个Uri并将其传递给base属性:

public new String Source {
  get {
    return base.Source.ToString();
  }
  set {
    if( !IsInDesignMode )
      return;
    base.Source = new Uri( value, UriKind.RelativeOrAbsolute );
  }
}

另请注意,如果您使用此方法(或任何其他已发现的方法,例如在资源文件中使用x:class并直接从xaml实例化)将导致样式在构建之前不会更新。使用标准ResourceDictionary将导致设计器在编辑导入的资源文件后立即更新(甚至在保存之前)。这也表明设计师在设计时不同地对待ResrouceDictionary。

希望有人觉得这很有用:)

答案 3 :(得分:0)

另一种方法(我们现在的方式):让预构建脚本注释掉所有XAML文件中的合并。

在DEBUG模式下调试内存问题等变得更加困难,但可以完全自动化并修复最终版本的问题。

答案 4 :(得分:0)

脚本的想法对我来说似乎不是一个好主意。你的源代码控制中有很多“假的”修改,我的猜测是你需要花很多时间来调整它。

我一直希望VS2010和Expression Blend 3能在这方面做出重大改进。有人试过beta并知道吗?

答案 5 :(得分:0)

您可以在App.xaml的Resources中添加资源字典,这对我来说非常有用。 或者可能是我没有得到你。