DependencyObject.AssociatedObject始终为null

时间:2011-04-04 16:49:34

标签: wpf

我正在尝试编写一个客户行为,如果我的“可见性”(在这种情况下只是一个bool)属性为false,则将某些列宽设置为0 ...我的问题是当我的on changed事件触发它时我的AssociatedObject始终为null。

以下是相关的示例代码,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");
}

感谢您的帮助......

2 个答案:

答案 0 :(得分:3)

你是如何附加行为的?你能展示一些行为代码吗?

在调用Attach之后或通过列出<i:Interaction.Behaviors></i:Interaction.Behaviors>

中的行为来设置AssociatedObject

答案 1 :(得分:0)

感谢MarkusHütter的想法。这就是我在PasswordBox Behavior中实现的方法(参见下面代码中的注释):

<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;
    }
}