2

DateTimePicker コントロールに Adorner を追加しましたが、他のコントロールの上に表示されません。なんで?どうすれば修正できますか?

私の崇拝者

私の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); };
    }
}
4

2 に答える 2

1

この問題は、によって管理される Adorners がAdornerDecoratorAdornerDecorator 内のコントロールの上にのみ表示されることが保証されているために発生するようです。代わりに、ウィンドウのほとんどのコンテンツを AdornerDecorator でラップする必要がありますが、これを行った後、AdornerLayer.GetAdornerLayer()状況によっては AdornerDecorator が表示されず、null が返されるようです。

ドキュメントには、「GetAdornerLayer は、指定された から始まるビジュアル ツリーをたどりUIElement、最初に見つかった adorner レイヤーを返す」と主張されています。実際には、少なくとも .NET 3.5 では、の外にある をGetAdornerLayer見つけることができません。私は自分自身を行うと主張していることを正確に行うことで問題を修正しました:AdornerDecoratorUserControlGetAdornerLayer

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

最後に、コンストラクターではなくイベントGetAdornerLayerから呼び出す必要があります。Loaded

于 2012-11-16T18:56:18.280 に答える
0

デフォルトの Window スタイルにはすでに adorner レイヤーがあり、その adorner レイヤーはウィンドウのコンテンツの上にあります。

したがって、UserControl から AdornerLayer を削除するだけで機能します。

于 2012-11-15T00:32:27.687 に答える