2013-07-18 106 views
6

檢查以下情形(其他人可能也適用),你可以創建項目只需複印件粘貼在這裏的代碼在正確的文件]:Visual Studio WPF設計器中的錯誤?

一個 - 建立一個具有基本的東西(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) }); 
     } 
    } 
} 

ç - 創建一個用戶控件從基部繼承(UserControl1.xaml):

<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得不到解決(並沒有加載測試BorderBrush)。 DynamicResources已解決(背景爲藍色),但設計人員說它無論如何都找不到資源(第一次工作正常,但是當您打開/關閉設計器時,資源無法解析)。非命名資源,如TextBlock樣式工作正常。

這是一個設計師錯誤還是我做錯了什麼?在資源永不改變的場景中,必須聲明資源爲動態的嗎?

enter image description here

在此先感謝。

+0

可以將資源聲明爲動態,只是效率不高。如果僅在此處使用此ResourceDictionary,是否嘗試將它添加到基類的XAML前端中的'UserControl.Resources'中,以查看其行爲是否有所不同? –

+0

@WillEddins:在我真正的應用程序中,資源被設置在一個基本的UserControl上,因此每個控件都有必要的資源,以便在WPF設計器上正確地看到它(否則這些樣式僅應用於運行時,並且我們無法進行適當的UI設計,除非啓動每次更改的應用程序:S)。 –

回答

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

+0

感謝您花費在此的時間。我們目前正在使用方法1,但我有點擔心警告(即使它不傷害它不應該在那裏)。解決方案2它不是一個選項,因爲基類資源有點複雜(您可以在運行時更改應用程序的樣式),因此涉及多個資源字典。爲了讓事情變得更加困難,我們希望在設計時看到控件,就像運行時一樣,所以我們只在設計時添加資源緩存(否則它們來自應用程序)。這就是爲什麼我們創建了一個基本的UserControl ... –

+0

你認爲我們應該向Ms提交一個bug嗎? –

+0

@SoMoS我有興趣聽到一個更熟悉設計師如何在構造函數和任何方面工作的人。然而,就運行時改變樣式而言,我通常希望在Application.Resources層次上看到一個'ResourceDictionary'的變化。即使您將示例中的ResourceDictionary定義爲靜態(因此在添加時共享它),您仍然需要按實例更改MergedDictionary,是不是?我相信你的實現是不同的,但似乎是一個複雜的方法去做。 –

相關問題