2013-05-07 15 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; 
    } 
} 

這令我真的很離奇。在這種簡單的情況下,我可以通過在OnTest1Property_Changed中執行初始化而不是在OnAttached中(儘管處於靜態上下文而不是實例上下文中的輕微不便)來解決該問題。

但是,如果我有一個相對較少的具有多個屬性的微不足道行爲?在某些使用行爲中,所有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 2013-05-08 09:24:18