首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何把WPF的装饰者画在其他的上面?

如何把WPF的装饰者画在其他的上面?
EN

Stack Overflow用户
提问于 2012-11-15 08:27:27
回答 2查看 5.2K关注 0票数 2

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

我的XAML目前是这样的:

代码语言:javascript
复制
<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的类,并添加到构造函数中:

代码语言:javascript
复制
public DateTimePicker()
{
    InitializeComponent();
    ...

    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(DateDisplay);
    if (adornerLayer != null)
    {
        adornerLayer.Add(_upDownBtns = new TextBoxUpDownAdorner(DateDisplay));
        _upDownBtns.Click += (textBox, direction) => { OnUpDown(direction); };
    }
}
EN

回答 2

Stack Overflow用户

发布于 2012-11-17 02:56:18

问题的出现显然是因为由AdornerDecorator管理的装饰器只能保证出现在AdornerDecorator内的控件之上。有必要将窗口的大部分内容包装在AdornerDecorator中,但是这样做之后,AdornerLayer.GetAdornerLayer()在某些情况下显然看不到AdornerDecorator,并返回null。

文档声称"GetAdornerLayer从指定的UIElement开始遍历可视化树,并返回它找到的第一个装饰器层。“实际上,GetAdornerLayer找不到位于UserControl之外的AdornerDecorator,至少在.NET 3.5中找不到。我修复了这个问题,做了GetAdornerLayer声称自己做的事情:

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2012-11-15 08:32:28

默认窗口样式中已经有一个装饰层,该装饰层位于窗口内容的上方。

因此,只需从UserControl中删除AdornerLayer就可以了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13389772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档