WPF에서 StaticResource와 DynamicResource의 차이점은 무엇입니까?


474

WPF에서 브러시, 템플릿 및 스타일과 같은 리소스를 사용하는 경우 StaticResources로 지정할 수 있습니다.

<Rectangle Fill="{StaticResource MyBrush}" />

또는 DynamicResource로

<ItemsControl ItemTemplate="{DynamicResource MyItemTemplate}"  />

대부분의 경우 (항상?) 하나만 작동하고 다른 하나는 런타임 중에 예외를 throw합니다. 그러나 나는 왜 그런지 알고 싶습니다.

  • 주요 차이점은 무엇입니까? 메모리 나 성능에 미치는 영향
  • "브러시는 항상 정적입니다"및 "템플릿은 항상 동적입니다"등과 같은 WPF 규칙이 있습니까?

나는 가정 이 보인다 동적 대 정적 사이의 선택은 임의적으로하지 않습니다 ...하지만 패턴을 볼 실패합니다.


27
Windows 8 앱 개발자에게는 DyanmicResource가 옵션이 아니라 StaticResource 만 있다는 점에 유의해야합니다.
Jerry Nixon

2
@Jerry Nixon 감사합니다. StaticResource 대신 DynamicResource를 사용했거나 그 반대의 경우도 작동하지 않는 횟수를 잃어 버렸습니다. 프로그래머의 관점에서 볼 때 이것은 복잡하지 않습니다. 유추는 변수 정의입니다. 힙 또는 스택에 있는지 여부를 명시 적으로 지정해야합니까? 그리고 내가 잘못하면 치명적인 런타임 오류가 발생합니까?
Contango

StaticResource 및 DynamicResource에 대한 자세한 설명과 사용시기에 대해서는 msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx를 참조 하십시오 .
Michael Repucci

답변:


466

정적 리소스는 해결하고 응용 프로그램이 실제로 실행되기 전에 발생하는 XAML의 로딩하는 동안 속성에 할당됩니다. 한 번만 지정되며 자원 사전에 대한 변경 사항은 무시됩니다.

DynamicResource은 로딩하는 동안 속성에 표현 개체를 할당하지만 식 개체 값을 요청하는 경우 실제로 런타임 때까지 자원을 조회하지 않습니다. 런타임에 필요할 때까지 리소스를 찾는 것을 지연시킵니다. XAML에서 나중에 정의 된 리소스에 대한 참조를 예로들 수 있습니다. 또 다른 예는 런타임까지는 존재하지 않는 리소스입니다. 소스 자원 사전이 변경되면 대상을 업데이트합니다.


4
DynamicResource를 사용하기 전에 무엇을 변경해야합니까? 예를 들어 템플릿을 가져 오십시오. 한 번 정의하면 트리거와 물건이 템플릿의 내용을 변경할 수 있지만 템플릿은 여전히 ​​동일합니다. StaticResource가 여기서할까요?
Isak Savo

5
연결하려는 리소스가 사용 지점 이전에 XAML에 정의되어 있고 애플리케이션 실행 기간 동안 변경되지 않는 경우 StaticResource를 사용하십시오. 이 경우 StaticResource로 더 나은 성능을 얻을 수 있습니다.
Phil Wright

4
두 가지 모두에 양방향 바인딩을 적용 할 수 있습니까? 그렇다면 그 차이는 무엇입니까?
WhoIsNinja

11
마지막 문장은 정말 중요합니다 :It will update the target if the source resource dictionary is changed.
MEMark

4
@IsakSavo 색상 테마가있는 UI를 고려하십시오. 동적 자원을 사용하면 하나의 사전을 다른 사전으로 바꿀 수 있으며 새 사전의 자원을 참조하는 모든 것이 자동으로 업데이트됩니다.
Gusdor

119

나는 또한 그들에 대해 혼란 스러웠다. 아래 예를 참조하십시오.

<Window x:Class="WpfApplicationWPF.CommandsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CommandsWindow" Height="300" Width="300">

    <StackPanel>
        <Button Name="ButtonNew" 
                Click="ButtonNew_Click" 
                Background="{DynamicResource PinkBrush}">NEW</Button>
        <Image Name="ImageNew" 
               Source="pack://application:,,,/images/winter.jpg"></Image>
    </StackPanel>


    <Window.Background>
        <DynamicResource ResourceKey="PinkBrush"></DynamicResource>
    </Window.Background>

</Window>

여기에서는 버튼과 창에 동적 리소스를 사용했으며 어디에서나 선언하지 않았습니다. 런타임에 계층의 ResourceDictionary가 확인됩니다.이를 정의하지 않았으므로 기본값이 사용됩니다.

버튼의 이벤트를 클릭하기 위해 아래 코드를 추가하면 DynamicResource를 사용하기 때문에 배경이 그에 따라 업데이트됩니다.

private void ButtonNew_Click(object sender, RoutedEventArgs e)
{
    this.Resources.Add(  "PinkBrush"
                         ,new SolidColorBrush(SystemColors.DesktopColor)
                       );
}

그들이 StaticResource를 사용한 경우 :

  • 리소스는 XAML로 선언해야합니다.
  • 그리고 "이전"도 사용됩니다.

혼동이 사라지기를 바랍니다.


31

StaticResource는 객체 생성시 해결됩니다.
제어에 자원이 필요할 때마다 DynamicResource가 평가되고 해결됩니다.


21
  1. StaticResource는 첫 번째 값을 사용 합니다. DynamicResource는 마지막 값을 사용 합니다.
  2. DynamicResource는 중첩 스타일에 사용할 수 있으며 StaticResource는 사용할 수 없습니다.

이 중첩 스타일 사전이 있다고 가정하십시오. LightGreen은 루트 레벨에 있고 Pink는 그리드 안에 중첩되어 있습니다.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Grid}">
        <Style.Resources>
            <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
                <Setter Property="Background" Value="Pink"/>
            </Style>
        </Style.Resources>
    </Style>
    <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
        <Setter Property="Background" Value="LightGreen"/>
    </Style>
</ResourceDictionary>

보기 :

<Window x:Class="WpfStyleDemo.ConflictingStyleWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ConflictingStyleWindow" Height="100" Width="100">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ConflictingStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Style="{DynamicResource ConflictButton}" Content="Test"/>
    </Grid>
</Window>

StaticResource는 버튼을 스타일에서 찾은 첫 번째 값인 LightGreen으로 렌더링합니다. DynamicResource는 그리드를 렌더링 할 때 LightGreen 버튼을 분홍색으로 재정의합니다.

정적 리소스 정적 리소스

DynamicResource DynamicResource

VS Designer는 DynamicResource를 StaticResource로 취급합니다. 첫 번째 가치를 얻습니다. 이 경우 VS Designer는 실제로 분홍색으로 끝나지만 버튼을 연두색으로 렌더링합니다.

루트 수준 스타일 (LightGreen)을 제거하면 StaticResource에서 오류가 발생합니다.


13

주요 차이점은 무엇입니까? 메모리 나 성능에 미치는 영향

정적 및 동적 리소스의 차이점은 기본 개체가 변경 될 때 발생합니다. Resources 컬렉션에 정의 된 Brush가 코드로 액세스되어 다른 객체 인스턴스로 설정된 경우 Rectangle은이 변경을 감지하지 않습니다.

정적 요소는 참조 요소에 의해 한 번 검색되어 리소스 수명 동안 사용됩니다. 반면 DynamicResources는 사용될 때마다 검색합니다.

동적 리소스의 단점은 응용 프로그램 성능이 저하되는 경향이 있다는 것입니다.

"브러시는 항상 정적입니다"및 "템플릿은 항상 동적입니다"등과 같은 WPF 규칙이 있습니까?

코드 뒤에있는 리소스를 동적으로 변경하려는 특별한 이유가없는 한 정적 리소스를 사용하는 것이 가장 좋습니다. 동적 재구성을 사용하지 않을 인스턴스의 또 다른 예로는 SystemBrushes, SystenFonts 및 시스템 매개 변수를 사용할 때가 있습니다.


7

모든 답변이 유용하다는 것을 알았으므로 유스 케이스를 하나 더 추가하려고했습니다.

복합 WPF 시나리오에서 사용자 컨트롤은 해당 리소스를 DynamicResource로 참조하여 다른 부모 창 / 컨트롤 (이 사용자 컨트롤을 호스팅 할)에 정의 된 리소스를 사용할 수 있습니다.

다른 사람들이 언급했듯이 Staticresource는 컴파일 타임에 조회됩니다. 사용자 컨트롤은 호스팅 / 부모 컨트롤에 정의 된 리소스를 참조 할 수 없습니다. 그러나이 경우 DynamicResource를 사용할 수 있습니다.


3

동적 자원의 중요한 이점

응용 프로그램을 시작하는 데 시간이 오래 걸리면 창이나 앱을 만들 때 항상 정적 리소스가로드되고 동적 리소스가 처음 사용될 때는로드되기 때문에 동적 리소스를 사용해야합니다.

그러나 리소스가 매우 크고 복잡하지 않으면 아무런 이점이 없습니다.


DynamicResources의 경우 성능 문제가 한 번만 발생합니까 (처음으로 사용됨) 또는 요소를 사용할 때마다 발생합니까?
Morgane

이 경우에 가장 많이 사용되는 필드는 정적 리소스 여야하고, 사용자 정의 사용 필드는 동적 일 수 있습니다. 즉,
메인

2

동적 자원은 설정중인 특성이 종속성 오브젝트에서 파생되거나 고정 자원을 어디에서나 사용할 수있는 고정 가능 오브젝트에있는 경우에만 사용할 수 있습니다. 정적 리소스를 사용하여 전체 제어를 추상화 할 수 있습니다.

정적 자원은 다음 상황에서 사용됩니다.

  1. 런타임시 반응 자원 변경이 필요하지 않은 경우.
  2. 많은 자원으로 좋은 성능이 필요한 경우.
  3. 동일한 사전 내에서 리소스를 참조하는 동안

동적 자원 :

  1. 속성 또는 스타일 설정 기 테마의 값은 런타임까지 알 수 없습니다
    • 여기에는 시스템, 응용 프로그램, 테마 기반 설정이 포함됩니다
    • 순방향 참조도 포함됩니다.
  2. 페이지, 창, usercontrol이로드 될 때로드되지 않을 수있는 큰 리소스를 참조합니다.
  3. 사용자 정의 컨트롤에서 테마 스타일 참조
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.