2014-03-07 4 views
6

ResourceDictionary에 정의 된 DataTemplate 내부에서 StaticResources를 참조 할 때 이상한 동작이 발생했습니다.DataTemplate 내의 StaticResource 참조

이 예제에서는 ResourceDictionary에 정의 된 DataTemplate을 사용하여 1에서 9까지의 숫자로 목록 상자를 채 웁니다.

<Window x:Class="testResources.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" 
    Width="525" 
    Height="350"> 
<Grid> 
    <ListBox Width="100" ItemTemplate="{StaticResource NumberTemplate}"> 
     <ListBox.ItemsSource> 
      <Int32Collection>1,2,3,4,5,6,7,8,9</Int32Collection> 
     </ListBox.ItemsSource> 
    </ListBox> 
</Grid> 

NumberTemplate이 ResourceDictionary1.xaml에 정의되어 있습니다 :

는 여기 MainWindow.xaml 코드 년대 정적 리소스 CoolNumbersColor이 응용 프로그램에 정의되어

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
<DataTemplate x:Key="NumberTemplate"> 
    <Grid Background="{StaticResource CoolNumbersColor}"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="35" /> 
     </Grid.ColumnDefinitions> 
     <TextBox Grid.Column="0" Background="{StaticResource CoolNumbersColor}" Text="{Binding Mode=OneWay}" /> 
    </Grid> 
</DataTemplate> 
.과 함께 xaml. 난 비주얼 스튜디오 2010 디자이너에서 예상되는 동작을 볼 수 있습니다 모든

<Application x:Class="testResources.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> 
<Application.Resources> 
    <ResourceDictionary> 
     <SolidColorBrush x:Key="CoolNumbersColor">GreenYellow</SolidColorBrush> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="pack://application:,,,/ResourceDictionary1.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

첫째, 여기 내 App.xaml 파일입니다. 실제로 색칠 된 숫자 목록이 나타납니다. 이 샘플을 실행하려고 할 때 나는 오류를받을

" 'CoolNumbersColor'라는 이름 리소스를 찾을 수 없습니다. 자원 이름은 대소 문자를 구분"

이런 일이 발생하는 이유는 이해할 수 없다. CoolNumbersColor 평가가 어떻게 되던가? 어휘 적으로 병합 된 resourcedictionary 앞에 있습니다.

이 작업을 수행하는 유일한 방법은 DynamicResources를 사용하는 것 외에는 두 번째 ResourceDictionary (예 : ResourceDictionary2)를 만드는 것입니다.XAML)이 CoolNumbersColor을 정의하고 다음과 같이 ResourceDictionary.MergedDictionaries에 그들 모두를 병합 :

<Application x:Class="testResources.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> 
<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="pack://application:,,,/ResourceDictionary2.xaml" /> 
      <ResourceDictionary Source="pack://application:,,,/ResourceDictionary1.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

+1

이 리소스를 어디에서 사용하십니까? 나는 작은 응용 프로그램에서 그것을 시도하고 내 끝에서 잘 작동합니다. –

+0

Application.Resources의 ResourceDictionary.MergedDictionaries 앞에 CoolNumbersColor를 정의하려고 했습니까? –

+0

예'ListBox'의'DataTemplate' 안에서 사용하고 사용했습니다. 여전히 문제는 없습니다. 작은 응용 프로그램으로 시도해 볼 수 있습니까? 나는 다른 곳에서 문제가 있다고 생각한다. –

답변

6

나는이 사실에 기인 같아요 A :

StaticResource

  • 정방향 참조를 지원하지 않습니다.
  • 로드 시간 DynamicResource

    • 앞으로 지원
    • 자원에 대한 각 액세스에 적용 참조 자원

    조회 : 런을 프로그램이 시작될 때 한 번만 설정 시간 조회

Example of forward reference

StaticResource 작동하지 :

<Window x:Class="SeveralResourceDictionariesHelp.MainWindow" 
     Background="{StaticResource testColor}" ... > 

<Window.Resources> 
    <SolidColorBrush x:Key="testColor">Red</SolidColorBrush> 
</Window.Resources> 

DynamicResource와 함께 : 사용할 수없는 응용 프로그램이 시작되는 시점에서

<Window x:Class="SeveralResourceDictionariesHelp.MainWindow" 
     Background="{DynamicResource testColor}" ... > 

<Window.Resources> 
    <SolidColorBrush x:Key="testColor">Red</SolidColorBrush> 
</Window.Resources> 

CoolNumbersColor (정적 리소스를) 내 " 가시성 "이 각각 DataTemplate 인 경우 예외가 발생하고 그것의 범위에서 그것을 찾으십시오 그러나 그것을 찾아 낼 수 없다.

리소스 사전을 사용할 때 리소스 사전을 사용할 때 리소스 큐브는 리소스가있는 단일 범위의 뷰일 것입니다.

DynamicResource은 응용 프로그램이 시작될 때로드되지 않고 첫 번째 요청시로드되고이 단계에서 DataTemplate은 리소스를 "확인"합니다.

질문이 남아 있습니다 : Why this trick works in the Studio?. 아마도 런타임과 디자인 모드에서로드 사이에 차이가 있지만 설명서 또는 다른 곳에서 공식 확인을 찾지 못했습니다.

+0

@Theodore Zographos : 네, 그렇습니다. 답안에 쓰고 싶었지만 자신을 한 단락으로 제한했습니다. –

+0

글쎄, 적어도 어휘 적으로, 나는 CoolReasonColor가 MergedDictionaries보다 먼저 정의되었으므로 앞으로 참조가 보이지 않는다. 파서가 DataTemplate을 평가할 때 lookup chain에 정의되어 있기 때문에'CoolNumbersColor'를 찾아야합니다 : 1.same xaml 2.Generic.xaml 3. app.resources –

+2

@Theodore Zographos : WPF에서 요소는 리소스 섹션에서 리소스를 먼저 찾은 다음 요소 트리의 루트까지 거품을 내고 마지막으로 시스템 테마에 도달합니다. 다음 시퀀스는 순서를 보여줍니다. 1. 요소 계층. 2. Application.Resources 3. 유형 테마 4. 시스템 테마. –