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 FrameworkElement
to 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);
}
}
}
}
}
}
}