我刚刚为我删除了一个大内存问题,我曾经在每个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
必须有更好的方法来设计页面和控件的设计时间,任何人都知道吗?
谢谢!
答案 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中添加资源字典,这对我来说非常有用。 或者可能是我没有得到你。