6

检查以下场景(其他情况也可能适用)[您可以创建项目,只需将代码复制粘贴到正确的文件中]:

a - 创建一个包含基本内容的 ResourceDictionary (Resources.xaml):

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <SolidColorBrush Color="Red" x:Key="Test" />

    <Style TargetType="{x:Type GroupBox}" x:Key="Test2" >
        <Setter Property="Background" Value="Blue" />
    </Style>

    <Style TargetType="{x:Type TextBlock}" >
        <Setter Property="Foreground" Value="Green" />
    </Style>
</ResourceDictionary>

b - 创建一个用户控件库,其他人将在其中继承包含基本资源 (UserControlBase.cs):

using System.Windows.Controls;
using System;
using System.Windows;

namespace ResourceTest
{
    public class UserControlBase : UserControl
    {
        public UserControlBase()
        {
            this.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("ResourceTest;component/Resources.xaml", UriKind.RelativeOrAbsolute) });
        }
    }
}

c - 创建一个继承自基础 (UserControl1.xaml) 的 UserControl:

<ResourceTest:UserControlBase x:Class="ResourceTest.UserControl1"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:ResourceTest="clr-namespace:ResourceTest"

             mc:Ignorable="d" 

             d:DesignHeight="300" 
             d:DesignWidth="300" >
    <Grid>
        <GroupBox BorderBrush="{StaticResource Test}" Margin="3" Header="Test" Style="{DynamicResource Test2}" >
            <TextBlock Text="TESTTEST" />
        </GroupBox>

    </Grid>
</ResourceTest:UserControlBase>

结果:StaticResources 未解析(并且未加载 Test BorderBrush)。DynamicResources 已解决(背景为蓝色),但设计器说它无论如何都找不到资源(第一次工作正常,但是当您打开/关闭设计器时,无法解析资源)。像 TextBlock 样式这样的非命名资源可以正常工作。

这是设计师的错误还是我做错了什么?在资源永远不会改变的情况下,是否必须将资源声明为动态的?

在此处输入图像描述

提前致谢。

4

1 回答 1

1

设计人员似乎无法解决MergedDictionaries在设计时在代码隐藏中定义的问题。

ResourceDictionary通过在 Initialize 之前移动 to 可以看到更糟糕的示例。

public UserControl1()
{
    this.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("TempProject;component/Resources.xaml", UriKind.RelativeOrAbsolute) });
    InitializeComponent();
}

在这种情况下,DynamicResource甚至无法在设计时解析,这表明设计时视图不一定像您期望的那样调用构造函数。我用 Visual Studio 2012 对此进行了测试,因此这种行为自 2010 年以来没有改变。

就您的原始测试代码而言,请注意StaticResource,无论设计时视图抛出的“错误”和缺少红色边框如何,都在运行时按预期成功绑定(出现红色边框)。

我看到两个选项:

  1. DynamicResource在设计时在必要时使用以解决这些问题。虽然您可以使用StaticResource,但相关的“错误”和缺乏设计时视图显然是个问题。其他答案似乎表明现在两者之间可能没有太大的性能差异。

  2. 只需在您的 中实例化 ResourceDictionary UserControl.Resources,不要从基类继承。当您使用基类压缩一些代码时,您并没有提高效率,因为ResourceDictionary每次都会创建一个新实例。由于您不能(AFAIK)从具有 XAML 前端的基类扩展,您可能会反对MergedDictionary在此抽象级别使用未引用。

于 2013-07-18T13:40:57.060 回答