1

I want to create Adorner for FrameworkElement in attached property. But in PropertyChangedCallback AdornerLayer for my element is null.

How can I solve this issue?

Currently I do this:

    private static void _OnIsModalAdornerAttachedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var element = d as FrameworkElement;

        bool oldValue = (bool)e.OldValue;
        bool newValue = (bool)e.NewValue;

        if (null != element && oldValue != newValue)
        {
            var descriptor = DependencyPropertyDescriptor.FromProperty(VisibilityProperty, typeof(FrameworkElement));

            if (newValue)
            {
                descriptor.AddValueChanged(element, element_VisibilityChanged);
            }
            else
            {
                descriptor.RemoveValueChanged(element, element_VisibilityChanged);
            }
    }


private static void element_VisibilityChanged(object sender, EventArgs e)
        {
            var element = sender as FrameworkElement;

            if (null != element)
            {
                var adornerLayer = AdornerLayer.GetAdornerLayer(element);

                if (null != adornerLayer)
                {
                    // check if adorner exists
                    bool isExists = false;
                    var adorners = adornerLayer.GetAdorners(element);
                    if (null != adorners)
                    {
                        foreach (var adorner in adorners)
                        {
                            if (adorner is ModalAdorner)
                            {
                                isExists = true;
                                break;
                            }
                        }
                    }

                    // add if is not presented
                    if (!isExists)
                    {
                        var modalAdorner = new ModalAdorner(element);
                        adornerLayer.Add(modalAdorner);

                        var visibilityBinding = new Binding { Path = new PropertyPath("Visibility"), Source = element };
                        modalAdorner.SetBinding(VisibilityProperty, visibilityBinding);
                    }
                }
            }
        }

Then I manually change Visibility property for my FrameworkElementto Hidden and then to Visible. But this way is not really true.

UPDATE

I solved this issue. Now I do so:

private static void _OnIsModalAdornerAttachedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var element = d as FrameworkElement;

        bool oldValue = (bool)e.OldValue;
        bool newValue = (bool)e.NewValue;

        if (null != element && oldValue != newValue)
        {
            if (newValue)
            {
                if (element.IsLoaded)
                {
                    _AttachAdorner(element);
                }
                else
                {
                    element.Loaded += (sender, args) =>
                    {
                        _AttachAdorner(element);
                    };
                }
            }
            else
            {
                // remove adorner
                var adornerLayer = AdornerLayer.GetAdornerLayer(element);

                if (null != adornerLayer)
                {
                    var adorners = adornerLayer.GetAdorners(element);

                    if (null != adorners)
                    {
                        foreach (var adorner in adorners)
                        {
                            if (adorner is ModalAdorner)
                            {
                                adornerLayer.Remove(adorner);
                            }
                        }
                    }
                }
            }
        }
    }
Y.Yanavichus
  • 2,387
  • 1
  • 21
  • 34
  • what exactly does not worK? this looks all good to me. if your problem is, that adornerLayer is null in your second method, then, have you checked, that your element is in the visual tree of your window, and there is an AdornerDecorator in that elements ancestor-chain? – Markus Hütter Mar 17 '11 at 10:25
  • @Markus Hütter: All choices are presented. – Y.Yanavichus Mar 17 '11 at 15:25
  • @Markus Hütter: The problem was: adorner layer for element hasn't initialized yet when the dependency property already set up. – Y.Yanavichus Mar 17 '11 at 15:35
  • yes, use Loaded Look this post, http://stackoverflow.com/questions/833943/watermark-textbox-in-wpf – nonocast Apr 16 '12 at 03:45

1 Answers1

1

The answer is in update: use Loaded event.

Y.Yanavichus
  • 2,387
  • 1
  • 21
  • 34