2009-09-01 7 views
22

다른 종속성 속성의 값을 사용하여 값이 계산되는 종속성 속성을 어떻게 등록 할 수 있습니까?다른 종속 종속 속성

.NET 속성 래퍼가 런타임에 WPF에 의해 무시되므로 getters 및 setter에 논리를 포함하면 안됩니다. 그 해결책은 일반적으로 PropertyChangedCallback을 사용하는 것입니다. 그러나 그것들은 정적이라고 선언됩니다.

public bool TestBool 
{ 
    get { return (bool)GetValue(TestBoolProperty); } 
    set 
    { 
    SetValue(TestBoolProperty, value); 
    TestDouble = ((value)?(100.0):(200.0)); // HERE IS THE DEPENDENCY 
    } 
} 
public static readonly DependencyProperty TestBoolProperty = 
    DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel)); 

public double TestDouble 
{ 
    get { return ((double)GetValue(TestDoubleProperty)); } 
    set { SetValue(TestDoubleProperty, value); } 
} 
public static readonly DependencyProperty TestDoubleProperty = 
    DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel)); 

만큼 순환 종속성 아니기 때문에,이를 달성하기 위해 적절한 방법이있다 : 예를 들어

이 인위적 작업을 수행하는 적절한 방법은 무엇인가?

답변

21

흠 ... 나는 당신이 종속성 속성 value coercion을 더 잘보아야한다고 생각합니다. 다음은 강압을 사용한 예입니다.

public class ViewModel : DependencyObject 
{ 
    public bool TestBool 
    { 
    get { return (bool)GetValue(TestBoolProperty); } 
    set { SetValue(TestBoolProperty, value); } 
    } 
    public static readonly DependencyProperty TestBoolProperty = 
    DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel), new PropertyMetadata(false, OnTestBoolPropertyChanged)); 

    private static void OnTestBoolPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
    var vm = (ViewModel)d; 
    vm.CoerceValue(TestDoubleProperty); 
    } 

    public double TestDouble 
    { 
    get { return ((double)GetValue(TestDoubleProperty)); } 
    set { SetValue(TestDoubleProperty, value); } 
    } 
    public static readonly DependencyProperty TestDoubleProperty = 
    DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel), new PropertyMetadata(0.0, null, OnCoerceTestDouble)); 

    private static object OnCoerceTestDouble(DependencyObject d, object baseValue) 
    { 
    var vm = (ViewModel) d; 
    var testBool = vm.TestBool; 
    return ((testBool) ? (100.0) : (200.0)); 
    } 
} 
+0

'CoerceValueCallback'을 사용했을 때의 장점은 무엇입니까? opedog처럼 다른 의존성 속성의 'PropertyChangedCallback'에서 직접 의존성 속성을 변경하는 것은 무엇입니까? 나는 당신이 더 적절한 방법 인 당신이 연결된 문서에서 수집하지만, 나는 실질적인 차이에 대해 궁금합니다. – Gregyski

+1

글쎄, 커플 이름 지정 :이 속성에 대한 바인딩을 끊지 않습니다 (즉,이 속성이 강제 바인딩 된 표현식의 대상인 경우 강제 변환 후 작동하지만 명시 적 세트 후에는 손실됩니다). 의존성 속성 값 해석에서 우선 순위가 더 높습니다 (즉 PropA = "Something"이라고하면 PropA == "Something"을 의미하지는 않습니다. 강요는 해당 할당을 무시할 수 있기 때문입니다). 속성의 이전 값을 기억합니다 (예 : 다음 번에 CoerceValue()를 호출하면 로컬로 설정된 값이 아니라 TestDouble의 원래 값이됩니다) – Anvaka

1

실제로 정확합니다. PropertyChangedCallback을 사용해야합니다. 방법은 다음과 같습니다.

public bool TestBool 
{ 
    get { return (bool)GetValue(TestBoolProperty); } 
    set 
    { 
    SetValue(TestBoolProperty, value); 
    } 
} 
public static readonly DependencyProperty TestBoolProperty = 
    DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel), 
    new PropertyMetadata(false, new PropertyChangedCallback(OnTestBoolChanged))); 

private static void OnTestBoolChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    ViewModel vm = d as ViewModel; 
    vm.TestDouble = value ? 100.0 : 200.0; 
} 

public double TestDouble 
{ 
    get { return ((double)GetValue(TestDoubleProperty)); } 
    set { SetValue(TestDoubleProperty, value); } 
} 
public static readonly DependencyProperty TestDoubleProperty = 
    DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel)); 
+0

감사합니다. 조사에서 어리석게도'PropertyChangedCallback'에 전달 된 것을 검사하지 않았습니다. 이 테스트 방법을 사용하기 위해 테스트 프로젝트를 조정했는데 제대로 작동합니다. 다음에 Anvaka의 솔루션을 시도 할 것입니다. – Gregyski