在WPF中共享应用程序资源

时间:2013-03-23 01:09:30

标签: c# wpf nested-resources

this page开始,我读到了:

  

如果您的应用程序使用自定义控件并在ResourceDictionary(或XAML Resources节点)中定义资源,建议您在Application或Window对象级别定义资源,或者在自定义控件的默认主题中定义它们。在自定义控件的ResourceDictionary中定义资源会对该控件的每个实例产生性能影响。

好的......现在,我有一个定义以下资源的UserControl:

<UserControl ...>
    <UserControl.Resources>
        <Namespace:ImagesConverter x:Key="ImagesConverter" ...
        <Storyboard x:Key="AnimationHide" ...
    </UserControl.Resources>

因此,由于我在运行时创建了不少于100个实例,因为MSDN教程说,最好将这些资源移动到MainWindow或App级别。移动它们的最佳位置在哪里? MainWindow级别,应用程序级别或资源文件?为什么?

然后......我如何在他们的新位置使用它们?假设我在UserControl中有这个代码:

m_AnimationHide = (Storyboard)Resources["AnimationHide"];

我应该如何修改它以反映这些变化?我应该如何修改以下UserControl XAML代码?

Source="{Binding Source={x:Static Properties:Resources.MyImage}, Converter={StaticResource ImagesConverter}}"

2 个答案:

答案 0 :(得分:2)

就我个人而言,我更倾向于使用App.xaml或单独ResourceDictionary将其全部添加到Window.Resources,这样可以消除Window xaml中的混乱。

这也允许您轻松地为您的应用程序创建Themes,因为您可以将它们集中在一个地方,这样您就可以复制现有的ResourceDictionary更改画笔颜色等,您可以选择ResourceDictionary 1}}您希望加载并轻松更改应用程序的整个外观。

至于访问Resouces中的Usercontrol,xaml方面没有任何区别,您将继续使用{StaticResource resourceKey},因为当您拨打StaticResource进行搜索时虽然Resource层次结构可以找到Resource

因此,如果您将资源从UserControl.Resources移至Window.ResourcesApplication.Resources,则无需更改通过{StaticResource resourceKey}访问的xaml代码中的任何内容。< / p>

对于隐藏在代码中的访问权限,您将使用FindResource("resourceKey")代替Resources["resourceKey"],因为FindResource会在Resource的层次结构中搜索StaticResource XAML。

示例:

m_AnimationHide = (Storyboard)FindResource("AnimationHide");

如果要修改特定控件中的任何这些资源并将其冻结,您只需为该实例创建一个副本

实施例

var animation = FindResource("AnimationHide") as Storyboard;

m_AnimationHide = animation.Clone();
m_AnimationHide.Completed += m_AnimationHide_Completed;

您还可以设置x:Shared="false"这将每次从资源返回一个新的动画实例,如果您有一个需要更改的复杂资源,这将通过您的应用程序保存复制/粘贴相同的动画。中的值。

<Storyboard x:Key="AnimationHide" x:Shared="false" />

然后您就可以在本地修改资源。

答案 1 :(得分:1)

我想扩展一下将资源从控制xaml中移出的原因。

就像你在MSDN库中读到的那样,将任何东西移到更高级别的唯一技术原因是保存资源(即内存)。 ResourceDictionary中的每个条目在运行时创建为对象(= instance!)并占用内存,初始化需要几个CPU周期。

现在抓住类似StoryBoard的东西:必须为控件的每个实例创建一个对象,该对象存储与控件的特定实例相关或甚至连接到控件的特定实例的数据(如执行动画的实例)它应该开车。除非您希望所有控件都以相同和并行的方式进行动画处理。

对我而言,在代码中使用Clone并没有多大意义,而不是首先将该东西放入xaml中。 xaml方法需要一些复制/粘贴,因此意味着在多个地方修改动画(如果你甚至可以在控件之间重复使用类似的东西),但它会删除代码要求并且仍然这样做:为控件的每个实例创建Storyboard的实例。