2009-09-03 3 views
1

확인 - 두 가지 추가 속성 (영문 텍스트, 불어 텍스트)이 포함 된 사용자 지정 레이블을 만들어 두 번째로 단순한 시나리오라고 생각했습니다. 현재는이 같은 구조 :WPF 사용자 지정 컨트롤 및 DependencyProperty를 통한 속성 표시

Public Class myCustomLabel 
    Inherits System.Windows.Controls.Label 

    Public myEnglishTextProperty As DependencyProperty = DependencyProperty.Register("myEnglishText", GetType(String), GetType(myCustomLabel), New PropertyMetadata("English", New PropertyChangedCallback(AddressOf TextChanged))) 
    Public myFrenchTextProperty As DependencyProperty = DependencyProperty.Register("myFrenchText", GetType(String), GetType(myCustomLabel), New PropertyMetadata("Francais", New PropertyChangedCallback(AddressOf TextChanged))) 

    Public Sub New() 
     'This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class. 
     'This style is defined in themes\generic.xaml 
     DefaultStyleKeyProperty.OverrideMetadata(GetType(myCustomLabel), New FrameworkPropertyMetadata(GetType(myCustomLabel))) 
    End Sub 

    Public Property myEnglishText() As String 
     Get 
      Return MyBase.GetValue(myFrenchTextProperty) 
     End Get 
     Set(ByVal value As String) 
      MyBase.SetValue(myFrenchTextProperty, value) 
     End Set 
    End Property 

    Public Property myFrenchText() As String 
     Get 
      Return MyBase.GetValue(myFrenchTextProperty) 
     End Get 
     Set(ByVal value As String) 
      MyBase.SetValue(myFrenchTextProperty, value) 
     End Set 
    End Property 

    Private Sub TextChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs) 
     If DesignerProperties.GetIsInDesignMode(Me) = True Then 
      Me.Content = myEnglishText 
     Else 
      If myUser.Language = "E" Then 
       Me.Content = myEnglishText 
      Else 
       Me.Content = myFrenchText 
      End If 
     End If 
    End Sub 
End Class 

내 검사 창 그리드 XAML은 간단하다 : 이것은 개발 환경에서 작동하는 것 같다

<Grid> 
     <my:myCustomLabel myEnglishText="English Text" myFrenchText="English Text" Height="25" Width="100" Background="Aqua" Foreground="Black"/> 
</Grid> 

- 영어와 프랑스어 텍스트를 변경 변경 설계 미리보기에서와 앱이 실행되고 테스트 창이 열릴 때 작동합니다. 그러나 첫 번째 시간 - 나는 검사 창에게 나는 다음과 같은 메시지가 두 번째 열 경우 :

'myEnglishText'속성이 이미 'myCustomLabel'에 의해 등록되었다.

종속성 속성 선언을 공유로 변경하면이 문제는 해결됩니다. 콘텐츠 (클래스로 인스턴스화해야 함)를 업데이트하십시오. 영어와 프랑스어 레이블이 변경되면 디자인 타임에 콘텐츠 속성을 업데이트하면됩니다.

이 방법이 있습니까? 또는 내가 필요로하는 것에 대한 의존성 속성 과잉이 있습니까?

답변

7

당신은 인스턴스 변수로 종속성 속성을 등록하고, 인스턴스 생성자 중에있다. 따라서 컨트롤을 인스턴스화 할 때마다 다시 등록되므로 두 번째 오류가 발생합니다. 당신이 발견 한 것처럼, 종속성 속성은 정적 (공유) 회원이해야

Public Shared myEnglishTextProperty As DependencyProperty = 
    DependencyProperty.Register("myEnglishText", GetType(String), GetType(myCustomLabel), 
    New PropertyMetadata("English", New PropertyChangedCallback(AddressOf TextChanged))) 

당신은 아마뿐만 아니라 공유 생성자에서가 아니라 인스턴스 생성자 이상 (유형 initialiser를) OverrideMetadata를 호출해야합니다.

공유해야하는 콜백 문제 : 예, 그렇지만 콜백에 대한 인수 중 하나는 라벨 인스턴스입니다. 그래서 그냥 레이블과 그에서 인스턴스 메서드를 호출하는 캐스팅 할 수 있습니다

private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    ((MyLabel)d).TextChanged(); 
} 

private void TextChanged() 
{ 
    // your code here 
} 

(용서의 C# 구문)

+0

감사합니다.의존성 객체 "d"는 내내 얼굴을 쳐다보고 있었고 결코 2와 2를 함께 사용하지 않았습니다. – Gatmando

2

"me"인스턴스에 액세스하고있어 콜백 메소드를 공유하지 않으려는 이유가 무엇입니까? 그게 전부라면 공유하고 "d"매개 변수를 사용하십시오. 나는 당신에게 코드를 보여줄 정도로 VB를 잘 모르지만, 단지 myCustomLabel 타입의 변수를 만들고 그것에 "d"를 할당한다. 그런 다음 해당 변수 (예 : "lbl")를 사용하십시오.

If DesignerProperties.GetIsInDesignMode(lbl) = True Then 
    lbl.Content = myEnglishText 
Else 
    If myUser.Language = "E" Then 
     lbl.Content = myEnglishText 
    Else 
     lbl.Content = myFrenchText 
    End If 
End If 
+0

당신에게 매트 감사 - 같은 대답을 아래와 같이 (I 답변으로 설정 때문에 완전성의) 하지만 네가 맞았 어. 도움에 감사드립니다. – Gatmando

1

또한 예제 코드에 약간의 버그가 있습니다. 이 문제를 사용해보십시오 : 대신이의

Public Property myEnglishText() As String 
    Get 
     Return MyBase.GetValue(myEnglishTextProperty) 
    End Get 
    Set(ByVal value As String) 
     MyBase.SetValue(myEnglishTextProperty, value) 
    End Set 
End Property 

을 :

Public Property myEnglishText() As String 
    Get 
     Return MyBase.GetValue(myFrenchTextProperty) 
    End Get 
    Set(ByVal value As String) 
     MyBase.SetValue(myFrenchTextProperty, value) 
    End Set 
End Property 
관련 문제