2011-04-04 111 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; 
    } 
}