2014-06-18 3 views
1

우리는이 문제에 대해 완전한 하루를 보냈으며 모든 예제를 작은 예제로 요약했습니다. 우리는 현재 Silverlight에서 WPF로 프로젝트를 변환 중입니다. 두 버전 모두 Silverlight에서 WPF에서만 작동합니다.연결된 속성 클래스의 메서드를 호출 할 때 DependencyProperty의 값이 null 인 경우

public class MyAttachedProperty 
{ 
    public static readonly DependencyProperty DescriptionProperty = DependencyProperty.RegisterAttached("Description", typeof(String), typeof(MyAttachedProperty), new PropertyMetadata(null, DescriptionPropertyChanged)); 

    public static String GetDescription(DependencyObject obj, String value) 
    { 
    return (String)obj.GetValue(DescriptionProperty); 
    } 

    public static void SetDescription(DependencyObject obj, String value) 
    { 
    obj.SetValue(DescriptionProperty, value); 
    } 

    private static void DescriptionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
    var MySuperbControl = d as MyControl; 
    Debug.WriteLine("The control's text is: " + MySuperbControl.Text); 
    } 

    public static void DoNothing() 
    { 

    } 
} 

우리는이 같은 우리의 통제를 구현 다음과 같이

public class MyControl : Control 
{ 
    public String Text 
    { 
    get { return (String)GetValue(TextProperty); } 
    set { SetValue(TextProperty, value); } 
    } 

    public static readonly DependencyProperty TextProperty = 
    DependencyProperty.Register("Text", typeof(String), typeof(MyControl), new PropertyMetadata(null, TextChanged)); 

    private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 

    } 
} 

그럼 우리가 연결된 속성을 가진 클래스가 :

우리는이 같은 문자열 형 DependencyProperty에 간단한 제어 할 수 있습니다 MainWindow.xaml :

<ContentControl x:Name="MyContentControl"> 
    <ContentControl.ContentTemplate> 
    <DataTemplate> 
     <local:MyControl x:Name="MyCntrl" Text="DefaultText" att:MyAttachedProperty.Description="Test"/> 
    </DataTemplate> 
    </ContentControl.ContentTemplate> 
</ContentControl> 

이 생성자는 다음과 같습니다.

public MainWindow() 
{ 
    MyAttachedProperty.DoNothing(); 
    InitializeComponent(); 
} 

이렇게하면 디버그 텍스트에 텍스트가 포함되지 않습니다. InitializeComponent() 다음에 DoNothing()을 호출하면 텍스트가 표시됩니다. 아무도 설명 할 수 없습니까, 왜? Silverlight에서는 두 가지 방법 모두 작동합니다. 또한 데이터 템플릿에서 컨트롤을 사용하지 않으면 두 가지 방식 모두 작동합니다.

+1

왜 이런 동작을하는지 설명 할 수는 없습니다. 그러나 Text 속성의 값이 첫 번째 위치에 있어야합니다. Afaik WPF는 XAML에서 속성 할당의 실행 순서를 보장하지 않습니다. – Clemens

답변

1

흥미로운 부작용입니다. DependencyProperty 등록이 일부 글로벌 컬렉션에 추가한다고 생각할 때 의미가 있습니다. 먼저 MyAttachedProperty에서 정적 생성자를 호출하면 먼저 컬렉션에 추가되고 먼저 객체에 대해 설정됩니다. 당신은 당신이

public MainWindow() 
    { 
     MyControl.DoNothing(); 
     MyAttachedProperty.DoNothing(); 
     InitializeComponent(); 
    } 

을 할 수있는 같은 빈 정적 메소드 DoNothing을 추가하여 MyControl에 먼저 실행하는 정적 생성자를 강제로 텍스트가

public MainWindow() 
    { 
     MyAttachedProperty.DoNothing(); 
     MyControl.DoNothing(); 
     InitializeComponent(); 
    } 

을 을 표시하거나 경우에 할 경우

빈 텍스트가 표시됩니다.