2013-04-01 2 views
0

간단한 종속성 속성이 있습니다. 단추가있는 사용자 정의 컨트롤이 있습니다. 호출자가 MyName이라는 속성을 "Hello"로 설정하도록합니다. 나는 의존성 프로퍼티 코드가 문자열 "World"를 마지막에 추가하기를 원한다. 다음은이 시도 내 코드는 다음과 같습니다종속성 속성의 setter 값은 어떻게 수정합니까?

#region MyNAME DEPENDENCY PROPERTY 
private string _myName; 
public string MyName 
{ 
    get { return this._myName; } //a breakpoint here never trips 
    set 
    { 
     this._myName = value; 
     this.OnPropertyChanged("MyName"); 
    } 
} 

public string MyName2 { get { return this._myName; } } //a breakpoint here will trip 

public static readonly DependencyProperty MyNameProperty = DependencyProperty.Register("MyName", typeof(string), typeof(MyTabControl), new PropertyMetadata("", OnMyNamePropertyChanged)); 

private static void OnMyNamePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
{ 
    MyTabControl myUserControl = dependencyObject as MyTabControl; 
    myUserControl.OnMyNamePropertyChanged(e); 
    myUserControl.OnPropertyChanged("MyName"); 
} 
private void OnMyNamePropertyChanged(DependencyPropertyChangedEventArgs e) 
{ 
    this.MyName = (string)e.NewValue + " World"; 
} 
#endregion //end MyNAME 

그리고 내 버튼 XAML 코드는 다음과 같습니다 내가 할

<local:MyTabControl MyName="Hello" /> 

:이 같은이 컨트롤이있는 페이지를로드 할 때

<Button Content="{Binding Path=MyName, Mode=OneWay}" /> 

"Hello World"라는 버튼이 아니라 "Hello"라고 쓰여진 버튼. 작동

<Button Content="{Binding Path=MyName2, Mode=OneWay}" /> 

: 내가 지금처럼에는 myname1를 이용할 수 있도록 버튼의 XAML 코드를 변경하면 이상한 부분입니다. getter 코드는 동일합니다 (위 코드 포함). _myName을 가져 오는 코드가 예상보다 일찍 호출되고 있다고 생각합니다. 나도 기대하지 않는 것은 MyName 게터가 결코 호출되지 않는 것입니다. 내가 거기에 브레이크 포인트를 놓을 때, 그것은 여행하지 않는다. 그러나 MyName2를 사용하도록 버튼 바인딩 경로를 변경하면 해당 getter에 놓는 중단 점이 이동합니다.

내가 뭘 잘못하고 있니? MyName 속성을 사용하고 내 버튼을 "Hello World"로 표시하려면 어떻게해야합니까? (두 번째 게터를 사용하지 않고)

EDIT : 새 코드 추가.

나는 당신의 제안을 모두 가져다가 내 C# 코드를 변경 단순히이 :

public string MyName 
{ 
    get { return (string)GetValue(MyNameCustomProperty); } 
    set { SetValue(MyNameCustomProperty, value + " World"); } 
} 
public static DependencyProperty MyNameCustomProperty = DependencyProperty.Register("MyName", typeof(string), typeof(MyTabControl)); 

(난 아직도 속성을 depency에 새로 온) 내 앞의 코드와 함께 있었다 나는 여전히 같은 문제가 있습니다 . 이 코드로 뭔가를 할 수 있습니까?

+0

사용자 정의 OnPropertyChanged 함수가 있다고 가정합니까?기본값은'PropertyChangedEventArgs'를 사용하는'string'을 사용하지 않습니다. –

+0

My 클래스'MyTabControl'은'INotifyPropertyChanged'를 구현합니다. 나는'this.PropertyChanged (...)'를 호출하는 간단한 OnPropertyChanged 이벤트 핸들러를 가지고있다. 나는 끈을 잡는다. 내가 붙여 넣은 코드에서 빠져 나온 것을 볼 수 있습니다. – user2023861

답변

1

값을 강제 변환해야합니다.

public string MyName 
{ 
    get { return (string)GetValue(MyNameCustomProperty); } 
    set { SetValue(MyNameCustomProperty, value); } 
} 
public static DependencyProperty MyNameCustomProperty = DependencyProperty.Register("MyName", typeof(string), typeof(MyTabControl), new PropertyMetadata("", MyPropertyChanged, CoerceCurrentReading)); 

private static void MyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    //contains coerced value 
} 

private static object CoerceCurrentReading(DependencyObject d, object value) 
{ 
    MyTabControl tab = (MyTabControl)d; 
    return (string)value + " World"; 
} 

이 "안녕하세요"가 "안녕하세요"에서 XAML 코드가 입력 한 값을 변경하는 가장 깨끗한 방법은 다음과 같습니다 나는 것을 어떻게 여기입니다.

1

여기서 문제는 실제 종속성 속성을 사용하지 않는 것입니다. 종속성 속성을 사용하려면 필드가 아닌 실제 종속성 속성 저장소를 사용해야합니다. 이 백업 저장소는 바인딩과 같은 항목이 해당 값으로 이동하는 곳입니다. 코드를 다음과 같이 변경하고 뒷받침 필드를 삭제하십시오.

public string MyName 
{ 
    get { return (string)this.GetValue(MyNameProperty); } 
    set { this.SetValue(MyNameProperty, value); } 
} 
+0

이 코드를 대신 사용하려고했는데, 여전히 같은 문제가 있습니다. 내 코드는 내 원래 게시물의 맨 아래에 있습니다. 세터에서 "월드"를 추가하지만 버튼에는 여전히 "Hello"만 표시됩니다. 코드를 잘못 입력 했습니까? – user2023861

0

알림이 발생하기 전에 설정되는 값을 변경하려고합니다.

public string MyName 
{ 
    get { return this._myName; } //a breakpoint here never trips 
    set 
    { 
     this._myName = (string)value + "World!"; 
     this.OnPropertyChanged("MyName"); 
    } 
} 

당신이 겪고있는 문제는 당신이 백업 필드를 설정한다는 것입니다 : 가장 간단한 해결책은 통지 후, 당신이 원하는에 백업 필드의 값을 설정하는 것입니다. 그런 다음 UI에 업데이트를 알리고 OnNotifyPropertyChanged를 트리거한다는 알림을받습니다. OnNotifyPropertyChanged는 배킹 필드를 변경하려고하는 속성이 변경된 후에 호출됩니다.

+0

그건 나를 위해 작동하지 않습니다. 그것은 나의 첫번째 시도와 비슷하다. 'OnMyNamePropertyChanged' 메소드에서'this.MyName = (string) e.NewValue + "World";'행을보십시오. "World"문자열을 추가합니다. 이는 호출 스택에서 한 단계 앞선 경우를 제외하고는 제안한 것을 수행합니다. – user2023861

관련 문제