Visual Studio WPF设计器中的错误?

时间:2013-07-18 09:21:57

标签: .net wpf visual-studio-2010 resources designer

检查以下场景(其他场景也可能适用)[您可以创建项目,只需在右侧文件中复制粘贴代码]:

a - 使用基本内容(Resources.xaml)创建ResourceDictionary:

<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 - 创建一个继承自Base(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样式)可以正常工作。

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

enter image description here

提前致谢。

1 个答案:

答案 0 :(得分:1)

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

通过将ResourceDictionary移至Initialize之前,可以看到更糟糕的例子。

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,但相关的“错误”和缺少设计时视图显然会成为问题。现在两者之间Other answers seem to indicate there may not be much performance difference

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