我已经在我的DateTimePicker control中添加了一个装饰器,但它没有显示在其他控件的顶部。为什么?我该如何修复它?

我的XAML目前是这样的:
<UserControl x:Class="IntelliMap.WPF.DateTimePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:wpftc="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
mc:Ignorable="d">
...
<AdornerDecorator>
<Grid>
...
<TextBox x:Name="DateDisplay"
HorizontalAlignment="Stretch" ...>
</TextBox>
...
</Grid>
</AdornerDecorator>
</UserControl>装饰器本身是一个独立于UserControl的类,并添加到构造函数中:
public DateTimePicker()
{
InitializeComponent();
...
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(DateDisplay);
if (adornerLayer != null)
{
adornerLayer.Add(_upDownBtns = new TextBoxUpDownAdorner(DateDisplay));
_upDownBtns.Click += (textBox, direction) => { OnUpDown(direction); };
}
}发布于 2012-11-17 02:56:18
问题的出现显然是因为由AdornerDecorator管理的装饰器只能保证出现在AdornerDecorator内的控件之上。有必要将窗口的大部分内容包装在AdornerDecorator中,但是这样做之后,AdornerLayer.GetAdornerLayer()在某些情况下显然看不到AdornerDecorator,并返回null。
文档声称"GetAdornerLayer从指定的UIElement开始遍历可视化树,并返回它找到的第一个装饰器层。“实际上,GetAdornerLayer找不到位于UserControl之外的AdornerDecorator,至少在.NET 3.5中找不到。我修复了这个问题,做了GetAdornerLayer声称自己做的事情:
static AdornerLayer GetAdornerLayer(FrameworkElement subject)
{
AdornerLayer layer = null;
do {
if ((layer = AdornerLayer.GetAdornerLayer(subject)) != null)
break;
} while ((subject = subject.Parent as FrameworkElement) != null);
return layer;
}
public DateTimePicker()
{
InitializeComponent();
...
this.Loaded += (s, e) =>
{
// not null anymore!
AdornerLayer adLayer = GetAdornerLayer(DateDisplay);
};
}最后,必须从Loaded事件而不是从构造函数调用GetAdornerLayer。
发布于 2012-11-15 08:32:28
默认窗口样式中已经有一个装饰层,该装饰层位于窗口内容的上方。
因此,只需从UserControl中删除AdornerLayer就可以了。
https://stackoverflow.com/questions/13389772
复制相似问题