代码之家  ›  专栏  ›  技术社区  ›  Tommaso Belluzzo

在WPF中共享应用程序资源

  •  4
  • Tommaso Belluzzo  · 技术社区  · 13 年前

    从…起 this page ,我读到:

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

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

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

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

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

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

    我应该如何修改它以反映这些更改?我应该如何修改下面的UserControl XAML代码段?

    Source="{Binding Source={x:Static Properties:Resources.MyImage}, Converter={StaticResource ImagesConverter}}"
    
    2 回复  |  直到 13 年前
        1
  •  5
  •   GEOCHET S.Lott    12 年前

    就我个人而言,我更喜欢使用 App.xaml 或分开 ResourceDictionary 将它们全部添加到 Window.Resources ,这样可以消除您 Window xaml的溶液。

    这也允许您轻松创建 Themes 对于您的应用程序,因为您将它们都放在一个地方,所以您可以复制现有的 字典资源 改变画笔的颜色等,你可以选择什么 字典资源 您希望加载并轻松地更改应用程序的整个外观。

    至于访问 Resouces 在您的 Usercontrol xaml方面没有区别,您将继续使用 {StaticResource resourceKey} 就像你打电话给 StaticResource 它搜索 Resource 层次结构以查找 资源 .

    因此,如果您将资源从 UserControl.Resources 窗口.资源 Application.Resources 不过,您不需要更改正在访问的xaml代码中的任何内容 {静态资源密钥} .

    至于代码背后的访问,您将使用 FindResource("resourceKey") 而不是 Resources["resourceKey"] FindResource 将在层次结构中搜索 资源 就像 静态源 在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" />
    

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

        2
  •  1
  •   GEOCHET S.Lott    12 年前

    我想扩展一下将资源移出控制xaml的理由。

    正如您在MSDN库中所读到的,将任何东西提升到更高级别背后的唯一技术原因是保护资源(即内存)。ResourceDictionary中的每个条目都在运行时创建为一个对象(=instance!),占用内存,初始化需要几个CPU周期。

    现在,像StoryBoard这样的东西的问题是:必须为它应该驱动的控件的每个实例创建一个对象,该对象存储与控件的特定实例相关甚至连接的数据,比如执行动画的实例。除非您希望所有控件都以相同和平行的方式设置动画。

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

    推荐文章