2011-04-04 243 views
2

我想寫一個客戶行爲來設置一些列寬度爲0,如果我的「可見性」(這只是一個布爾在這種情況下)屬性是錯誤的...我的問題是,當我的更改事件觸發它我的AssociatedObject始終爲空。DependencyObject.AssociatedObject始終爲空

這裏是相關的示例代碼,mybe有人可以看到我哪裏出錯了。

public static readonly DependencyProperty VisibilityProperty = 
     DependencyProperty.Register("Visibility", typeof(bool), typeof(HideRadGridViewColumnBehavior), 
     new PropertyMetadata(OnVisibilityPropertyChanged)); 

private static void OnVisibilityPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) 
{ 
    if (((HideRadGridViewColumnBehavior)target).AssociatedObject == null) 
    MessageBox.Show("AssociatedObject is null"); 
} 

感謝您的幫助......

+0

轉到AssociatedObject的財產,使右按鍵點擊 - >查找用法。你會發現屬性設置爲null或者根本沒有設置。 – vorrtex 2011-04-04 17:39:08

+0

正確 - 但是這是從XAML設置,它實際上並沒有生成代碼,直到你編譯應用程序...我的意思是,我可能不是說的正確,但你明白了,重點是我贏了在代碼中看不到任何引用。 – Kenn 2011-04-04 17:50:00

+0

之後,你可以把斷點放在這個屬性的setter中。看來xaml代碼沒有將該值設置爲此屬性。 – vorrtex 2011-04-04 18:28:04

回答

3

你是如何連接的行爲?你能展示一些行爲的代碼嗎?

的AssociatedObject的設置無論是來電後Attach或通過<i:Interaction.Behaviors></i:Interaction.Behaviors>

+0

這就是行爲被設置的方式... 1 – Kenn 2011-04-04 19:52:06

+0

Oh - The行爲沒有任何代碼,但只會發生在我的OnVisibilityPropertyChanged中,但如果我無法訪問AssociatedObject,我什麼也做不了。 :( – Kenn 2011-04-04 20:01:48

+3

@Kenn,OK,那麼可能是綁定發生在連接之前發生的事情,無論你在你的改變處理器中有什麼,把它放在一個單獨的方法中,你可以調用你改變的處理器,然後在你的行爲中覆蓋'OnAttached()'並從那裏調用該方法,那麼一切都應該沒問題 – 2011-04-04 20:04:24

0

感謝馬庫斯·特內上市的行爲理念。這是我如何PasswordBox行爲實施(見下面的代碼註釋):

<PasswordBox> 
        <i:Interaction.Behaviors> 
         <behaviours:PasswordBehavior Password="{Binding Password, Mode=TwoWay}" /> 
        </i:Interaction.Behaviors> 
       </PasswordBox> 

行爲:

public class PasswordBehavior : Behavior<PasswordBox> 
{ 
    public static readonly DependencyProperty PasswordProperty = 
    DependencyProperty.Register("Password", typeof(string), typeof(PasswordBehavior), new PropertyMetadata(default(string))); 

    private object _value; 

    private bool _skipUpdate; 

    public string Password 
    { 
     get { return (string)GetValue(PasswordProperty); } 
     set { SetValue(PasswordProperty, value); } 
    } 

    protected override void OnAttached() 
    { 
     // in my case on OnAttached() called after OnPropertyChanged 
     base.OnAttached(); 

     AssociatedObject.PasswordChanged += PasswordBox_PasswordChanged; 

     // using _value saved before in OnPropertyChanged 
     if (_value != null) 
     { 
      AssociatedObject.Password = _value as string; 
     } 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.PasswordChanged -= PasswordBox_PasswordChanged; 
     base.OnDetaching(); 
    } 

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
    { 
     // in my case this called before OnAttached(), so that's why AssociatedObject is null on first call 
     base.OnPropertyChanged(e); 
     if (AssociatedObject == null) 
     { 
      // so, let'save the value and then reuse it when OnAttached() called 
      _value = e.NewValue as string; 
      return; 
     } 

     if (e.Property == PasswordProperty) 
     { 
      if (!_skipUpdate) 
      { 
       _skipUpdate = true; 
       AssociatedObject.Password = e.NewValue as string; 
       _skipUpdate = false; 
      } 
     } 
    } 

    private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) 
    { 
     _skipUpdate = true; 
     Password = AssociatedObject.Password; 
     _skipUpdate = false; 
    } 
}