2013-05-07 1 views
2

여기 간단한 블렌드 동작이 있습니다. 그것에는 하나의 DependencyProperty이 있습니다. 이것들은 초기화 중에 무언가를하고 싶습니다. OnAttached. 하지만 동작이 초기화되기 전에 첨부 된 것처럼 보일 수는 없습니다.블렌드 동작의 DependencyProperties를 초기화하는 동안 어떻게 사용합니까?

사용법 :

<Button> 
    <e:Interaction.Behaviors> 
     <local:TestBehavior Test1="{Binding ValueOnViewModel}"/> 
    </e:Interaction.Behaviors> 
<Button> 

정의 :이 날 같은 정말 기괴한 파업

class TestBehavior : Behavior<FrameworkObject> 
{ 
    public static readonly DependencyProperty Test1Property 
     = DependencyProperty.Register("Test1", typeof(int), typeof(TestBehavior), 
     new PropertyMetadata(OnTest1Property_Changed)); 

    private static void OnTest1Property_Changed(DependencyObject sender, 
     DependencyPropertyChangedEventArgs args) 
    { 
     // This gets called _after_ OnAttached! 
    } 

    public int Test1 
    { 
     get { return (int)GetValue(Test1Property); } 
     set { SetValue(Test1Property, value); } 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     // No matter what Test1Property is bound to in XAML 'a' will be default 
     // value because as this point the Behavior is attached, but not 
     // initialized! 
     int a = Test1; 
    } 
} 

. 이 간단한 경우에는 OnAttached가 아닌 OnTest1Property_Changed에서 초기화 작업을 수행하여이 문제를 해결할 수 있습니다 (인스턴스 컨텍스트가 아닌 정적 컨텍스트에 있음).

그러나 여러 속성이있는 다소 덜 사소한 동작이있는 경우 어떻게해야합니까? 행동의 일부 용도에서는 모든 DP가 명시 적으로 설정 될 수 있지만 다른 경우에는 명시 적으로 설정되지 않은 DP의 기본값을 사용하는 동안 일부 DP 만 설정 될 수 있습니다. 모든 DP의 동작이 정의하는 변경 이벤트를 처리 할 수는 있지만 클라이언트가 XAML에서 명시 적으로 설정 한 DP를 알 수있는 방법이 없으므로 초기화가 완료되기 전에 변경 알림이 발생해야합니다. .

그렇다면 동작의 초기화가 완료되면 어떻게 알 수 있습니까? 이것은 눈부신 약점처럼 보였습니다. 나는 분명히 뭔가를 놓쳤다 고 가정 할 수 있습니다.

내가 대신 내 행동의 기본으로 사용할 수있는이 간단한 기본 클래스를 노크 Sorskoot의 제안을 사용하여 [업데이트]

.

public class BehaviorBase<T> : Behavior<T> where T : FrameworkElement 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.Loaded += AssociatedObject_Loaded; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     AssociatedObject.Loaded -= AssociatedObject_Loaded; 
    } 

    protected virtual void OnLoaded() 
    { 

    } 

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e) 
    { 
     OnLoaded(); 
    } 
} 

답변

2

은 내가 OnAttached 방법 중 Loaded 이벤트에 부착 제안 당신은 거기에 초기 환경 않습니다.

protected override void OnAttached() 
{ 
     base.OnAttached(); 

     base.AssociatedObject.Loaded += onloaded; 
} 

private void onloaded(object sender, RoutedEventArgs e) 
{ 
     int a = Test1; 
     // Test1 should contain a value here. 
} 
+0

그건 고맙습니다. – Neutrino

관련 문제