다음을 통해 공유


WPF 및 Silverlight Designer 로드 실패 문제 해결

WPF Designer for Visual Studio에는 XAML을 렌더링하는 정교하며 확장 가능한 시각적 디자이너가 포함되어 있습니다. 디자이너에서 XAML 파일이 로드되지 않는 경우 몇 가지 방법을 통해 무엇이 문제인지 알아낼 수 있습니다. 이 항목에서는 WPF Designer 로드 실패 문제를 해결하는 데 도움이 되는 몇 가지 팁과 방법에 대해 설명합니다. 이 항목의 예제는 WPF에 중점을 두지만 대부분의 문제, 방법 및 해결 방법은 WPF와 Silverlight에 모두 적용됩니다.

참고

이 항목에서 설명하는 대부분의 방법은 Expression Blend에도 적용됩니다.

로드 실패 디버깅

Visual Studio 디버거를 사용하여 디자인 타임에 코드를 한 단계씩 실행하십시오. Visual Studio의 두 번째 인스턴스를 사용하여 로드 실패를 디버깅할 수 있습니다. 자세한 내용은 방법: 디자이너 로드 실패 디버그을 참조하십시오.

문제 해결 단계

다음 단계를 수행하면 WPF Designer 로드 실패 문제를 해결하는 데 도움이 됩니다.

  1. 표시된 예외 메시지가 있으면 자세히 읽어 보십시오.

    당연한 것처럼 보일 수도 있지만 예외 메시지가 표시되면 메시지의 내용을 명확하게 이해해야 합니다. 간혹 이렇게 하면 문제를 신속하게 진단하는 데 도움이 됩니다. 자세한 내용은 WPF Designer의 오류 디버깅 및 해석을 참조하십시오.

  2. 문제가 구현 내부에 있는지 확인하십시오.

    응용 프로그램을 빌드하고 실행하여 문제가 구현으로 인한 것인지 아니면 WPF Designer와의 상호 작용으로 인한 것인지 확인합니다. 응용 프로그램이 빌드되고 실행되면 구현으로 인해 디자인 타임 오류가 발생했을 수 있습니다.

  3. 로드 오류로 인한 문제인지 확인하십시오.

    예외로 인해 디자인 뷰가 로드되지 않으면 로드 오류로 인해 문제가 발생했을 수 있습니다. 디자인 타임에 로드된 사용자 지정 코드가 있고 디자인 타임에 예외 또는 로드 실패가 발생할 경우 이 항목의 디자인 타임용 코드 작성 단원을 참조하십시오.

  4. 디자인 타임에 로드된 코드를 검토하십시오.

    디자인 타임에도 실행되는 코드를 작성하는 방법은 두 가지입니다. 첫 번째 방법은 클래스에 대한 입력 매개 변수를 검사하여 안전한 코드를 작성하는 것입니다. 두 번째 방법은 GetIsInDesignMode 메서드를 호출하여 디자인 모드가 활성 상태인지 여부를 확인하는 것입니다. 자세한 내용은 이 항목의 디자인 타임용 코드 작성 단원을 참조하십시오.

  5. 코드의 다른 부분을 검토하십시오.

    WPF Designer를 사용할 때 도움이 되는 몇 가지 프로그래밍 팁을 보려면 이 항목의 프로그래밍 팁 단원을 참조하십시오. 보다 강력한 코드를 작성하는 방법은 이 항목의 최선의 프로그래밍 방법 단원을 참조하십시오.

  6. 그래도 문제가 해결되지 않으면 WPF Designer forum on MSDN에서 WPF Designer를 사용하는 다른 개발자와 정보를 교환하십시오. 잠재적 문제를 보고하거나 의견을 제안하려면 Visual Studio and .NET Framework 피드백 사이트를 이용하십시오.

디자인 타임용 코드 작성

코드는 런타임과 디자인 타임에 모두 실행되어야 합니다. 코드가 디자인 타임에 실행되더라도 Application.Current가 사용자 응용 프로그램이라고 단정하지 마십시오. 예를 들어, Expression Blend를 사용할 경우 Current는 Expression Blend입니다. 디자인 타임에는 MainWindow가 사용자 응용 프로그램의 주 창이 아닙니다. 사용자 지정 컨트롤이 디자인 타임에 로드되지 않게 하는 일반적인 작업에는 다음이 포함됩니다.

디자인 타임용 코드를 작성하는 방법은 두 가지입니다. 첫 번째 방법은 값 변환기와 같이 클래스에 대한 입력 매개 변수를 검사하여 안전한 코드를 작성하는 것입니다. 두 번째 방법은 GetIsInDesignMode 메서드를 호출하여 디자인 모드가 활성 상태인지 여부를 확인하는 것입니다. Silverlight의 경우 IsInDesignTool 속성을 사용합니다.

디자인 환경은 일부 입력에 대해 런타임 환경보다 다양한 형식을 제공하므로 일부 구현의 경우 입력 매개 변수 검사가 반드시 필요합니다.

스타일 선택기와 값 변환기의 경우 디자인 타임에 올바르게 실행되려면 이 두 방법 중 하나를 사용해야 합니다.

값 변환기

사용자 지정 IValueConverter 구현은 null이 있는지, 그리고 Convert 메서드의 첫 번째 매개 변수에 필요한 형식이 있는지 검사해야 합니다. 다음 XAML은 값 변환기가 올바르게 구현되지 않은 경우 디자인 타임에 실패하는 Application.Current에 대한 바인딩을 보여 줍니다.

<ComboBox.IsEnabled>
    <MultiBinding Converter="{StaticResource specialFeaturesConverter}">
        <Binding Path="CurrentUser.Rating" Source="{x:Static Application.Current}"/>
        <Binding Path="CurrentUser.MemberSince" Source="{x:Static Application.Current}"/>
    </MultiBinding>
</ComboBox.IsEnabled>

Application.Current가 사용자의 응용 프로그램이 아니라 디자이너 응용 프로그램을 참조하므로 이 바인딩은 디자인 타임에 예외를 발생시킵니다. 예외가 발생하지 않도록 하려면 값 변환기가 입력 매개 변수 또는 디자인 모드를 검사해야 합니다.

다음 코드 예제에서는 두 입력 매개 변수가 특정 비즈니스 논리를 만족할 경우 true를 반환하도록 값 변환기를 통해 입력 매개 변수를 검사하는 방법을 보여 줍니다.

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    // Check the values array for correct parameters.
    // Designers may send null or unexpected values.
    if (values == null || values.Length < 2) return false;
    if (!(values[0] is int)) return false;
    if (!(values[1] is DateTime)) return false;

    int rating = (int)values[0];
    DateTime date = (DateTime)values[1];

    // If the user has a good rating (10+) and has been a member for 
    // more than a year, special features are available.
    if((rating >= 10) && 
        (date.Date < (DateTime.Now.Date - new TimeSpan(365, 0, 0, 0))))
    {
        return true;
    }
    return false;
}

두 번째 방법은 디자인 모드가 활성 상태인지 여부를 확인하기 위해 디자인 타임용 코드를 작성하는 것입니다. 다음 코드 예제에서는 앞에서 보여 준 매개 변수 검사 대신 디자인 모드 검사를 보여 줍니다.

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    // Check for design mode. 
    if ((bool)(DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)) 
    {
        return false;
    }

    int rating = (int)values[0];
    DateTime date = (DateTime)values[1];

    // If the user has a good rating (10+) and has been a member for 
    // more than a year, special features are available.
    if((rating >= 10) && 
        (date.Date < (DateTime.Now.Date - new TimeSpan(365, 0, 0, 0))))
    {
        return true;
    }
    return false;
}

스타일 선택기

사용자 지정 스타일 선택기도 디자인 모드에서 실행되도록 구현해야 합니다. 다음 XAML은 DataTemplate으로 반환되는 리소스를 결정하기 위해 런타임에 Application.MainWindow를 사용하는 사용자 지정 템플릿 선택기를 보여 줍니다. 디자인 타임에 이 리소스를 사용할 수 없을 수도 있으므로 SelectTemplate 재정의가 디자인 타임에 null을 반환합니다.

<local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/>
<ListBox Width="400" Margin="10"
    ItemsSource="{Binding Source={StaticResource myTodoList}}"
    ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
    HorizontalContentAlignment="Stretch" 
    IsSynchronizedWithCurrentItem="True"/>

다음 코드에서는 스타일 선택기의 구현을 보여 줍니다.

public class TaskListDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(
        object item, 
        DependencyObject container)
    {
        if (item != null && item is Task)
        {
            Task taskitem = item as Task;
            Window window = Application.Current.MainWindow;

            // To run in design mode, either test for the correct window class
            // or test for design mode.
            if (window.GetType() == typeof(MainWindow))
            // Or check for design mode: 
            //if (!DesignerProperties.GetIsInDesignMode(window))
            {
                if (taskitem.Priority == 1)
                return window.FindResource("importantTaskTemplate") as DataTemplate;
                else
                return window.FindResource("myTaskTemplate") as DataTemplate;
            }
        }
        return null;
    }
}

프로그래밍 팁

다음은 WPF Designer를 사용할 때 도움이 되는 몇 가지 프로그래밍 팁입니다.

최선의 프로그래밍 방법

다음은 WPF Designer용의 보다 강력한 코드를 작성하기 위한 몇 가지 최선의 프로그래밍 방법입니다.

  • 항상 using 문 또는 try/finally 블록 내에 편집 범위를 래핑합니다. 예외가 발생하면 Dispose 호출에서 변경이 중단됩니다. 자세한 내용은 ModelEditingScope를 참조하십시오.

  • ModelEditingScope를 사용하여 컨트롤을 한 컨테이너에서 다른 컨테이너로 이동합니다. 이렇게 하지 않으면 예외가 발생합니다.

  • 기본값을 제거하려면 WPF와 WPF Designer에서 속성 값을 기본값으로 설정하지 않도록 합니다. Height와 같은 NaN 값의 경우 NaN을 할당하는 대신 ClearValue 메서드를 호출합니다.

  • 속성에서 값을 검색할 때 속성의 계산 값을 사용합니다. 즉, ModelItemGetCurrentValue 메서드 대신 ComputedValue 속성을 사용합니다. GetCurrentValue 메서드는 XAML에 저장된 바인딩 및 다른 식을 반환하므로 간혹 캐스팅 예외가 발생할 수 있습니다.

참고 항목

개념

예외 처리(디버깅)

기타 리소스

방법: 디자이너 로드 실패 디버그

WPF Designer의 오류 디버깅 및 해석

XAML 및 코드 연습