WPF 合并资源字典不一致

发布于 2024-08-20 21:32:35 字数 3495 浏览 7 评论 0 原文

我有一个 ResourceDictionary,它由一个 Brush 对象和一个 Style 组成,该 Style 使用此 Brush 对象来实现其 Template 属性中的多个动画属性(通过 StaticResource 标记扩展)。问题是;当我将字典与全局应用程序 ResourceDictionary (Application.Resources) 合并时,画笔不会被冻结,并且共享样式的每个元素都会受到画笔更改的影响。

有趣的是,当我将画笔移动到辅助合并的 ResourceDictionary 时,它会被冻结并且一切都按预期工作(freezable 在动画之前被克隆)仅当可冻结对象和其他一些资源通过 StaticResource 标记引用该对象时才会出现问题扩展驻留在同一合并的 ResourceDictionary 中。我在下面粘贴了 App.xaml、Window.xaml 和 Dictionary.xaml 的示例代码。如果您能够重现相同的结果并确认这是 WPF 中的错误,我将不胜感激。

注意:如果在 Visual Studio 中将 ResourceDictionary (Dictionary.xaml) 的内容类型从“页面”更改为“资源”(并将 XAML 而不是 BAML 版本嵌入到已编译的程序集中),问题就会消失。

窗口.xaml

<Window x:Class="WpfApplication1.Window" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300">
<StackPanel>
    <Button Height="30" Content="Test 1" Margin="5" />
    <Button Height="30" Content="Test 2" Margin="5" />
</StackPanel>

App.xaml

<Application x:Class="WpfApplication.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window.xaml">
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

字典.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="backgroundBrush" Color="Aqua" />

<Style TargetType="{x:Type Button}">
    <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate TargetType="{x:Type Button}">
                 <Border Name="border" Background="{StaticResource backgroundBrush}">
                     <ContentPresenter />
                 </Border>

                 <ControlTemplate.Triggers>
                     <Trigger Property="IsPressed" Value="True">
                        <Trigger.EnterActions>
                             <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Opacity" To="0" Duration="0:0:.2" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>

                         <Trigger.ExitActions>
                             <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Opacity" To="1" Duration="0:0:.2" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.ExitActions>
                    </Trigger>
                 </ControlTemplate.Triggers>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>

I have a ResourceDictionary, which consists of a Brush object and a Style using this Brush object for several animated properties in its Template property (via StaticResource markup extension). The problem is; when I merge the dictionary with the global application ResourceDictionary (Application.Resources) the Brush does not get freezed and every element sharing the Style gets affected by changes to the Brush.

Interestingly enough, when I move the Brush to a secondary merged ResourceDictionary, it gets freezed and everything works as expected (The freezable gets cloned before being animated) The problem happens only when a freezable object and some other resource referencing this object via the StaticResource markup extension reside in the same merged ResourceDictionary. I pasted the sample code for App.xaml, Window.xaml and Dictionary.xaml below. I would greatly appreciate if you could reproduce the same result and confirm that this is a bug in WPF.

NOTE: If you change the content type of the ResourceDictionary (Dictionary.xaml) from Page to Resource in Visual Studio (and thereof embed a XAML instead of BAML version of it into the compiled assembly) the problem disappears.

Window.xaml

<Window x:Class="WpfApplication1.Window" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300">
<StackPanel>
    <Button Height="30" Content="Test 1" Margin="5" />
    <Button Height="30" Content="Test 2" Margin="5" />
</StackPanel>

App.xaml

<Application x:Class="WpfApplication.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window.xaml">
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Dictionary.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="backgroundBrush" Color="Aqua" />

<Style TargetType="{x:Type Button}">
    <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate TargetType="{x:Type Button}">
                 <Border Name="border" Background="{StaticResource backgroundBrush}">
                     <ContentPresenter />
                 </Border>

                 <ControlTemplate.Triggers>
                     <Trigger Property="IsPressed" Value="True">
                        <Trigger.EnterActions>
                             <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Opacity" To="0" Duration="0:0:.2" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>

                         <Trigger.ExitActions>
                             <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Opacity" To="1" Duration="0:0:.2" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.ExitActions>
                    </Trigger>
                 </ControlTemplate.Triggers>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

橘虞初梦 2024-08-27 21:32:35

这是想要的功能。但您仍然可以通过演示选项 xml 命名空间冻结画笔,如下所示: http://blog.lexique-du-net.com/index.php?post/2010 /04/12/直接在 XAML 中冻结画笔以提高应用程序的性能

问候,

This is the wanted feature. But you can still freeze the brushes via the presentation options xml namespace as pointed out here : http://blog.lexique-du-net.com/index.php?post/2010/04/12/Freeze-brushes-directly-in-the-XAML-to-improve-your-application-s-performances

Regards,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文