4

这个页面,我读到:

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

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

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

因此,正如 MSDN 教程所说,由于我在运行时创建了不少于 100 个实例,因此最好将这些资源移动到 MainWindow 或 App 级别。把他们搬到哪里最好?MainWindow 级别、App 级别还是资源文件?为什么?

然后......我怎样才能从他们的新位置使用它们?假设我的 UserControl 中有这段代码:

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

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

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

2 回答 2

4

就个人而言,我更喜欢使用App.xaml或单独ResourceDictionary将它们全部添加到.Window.ResourcesWindow

这也使您可以轻松地Themes为您的应用程序创建它们,因为您将它们全部放在一个地方,因此您可以复制现有的ResourceDictionary更改画笔颜色等,您可以选择ResourceDictionary要加载的内容并轻松更改应用程序的整个外观。

至于Resouces在您Usercontrol的 xaml 端访问没有区别,您将继续使用{StaticResource resourceKey}as 当您调用StaticResource它时,它会通过Resource层次结构搜索以找到Resource.

因此,如果您将资源从UserControl.Resources移至 ,Window.Resources或者Application.Resources您不需要更改正在访问的 xaml 代码中的任何内容{StaticResource resourceKey}

至于后面代码中的访问,您将使用FindResource("resourceKey")而不是Resources["resourceKey"] asFindResource将在层次结构中搜索 xaml 中的Resource类似StaticResource行为。

例子:

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" />

然后您将能够在本地修改资源。

于 2013-03-23T01:30:51.777 回答
1

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

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

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

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

于 2013-03-23T03:10:29.527 回答