使用Adorner显示包含UIElements的拉伸叠加层

时间:2014-07-01 17:10:42

标签: c# wpf adorner

单击按钮时,我使用Adorner创建叠加层。该叠加层包含一个表格,例如基于其他UIElement s(ButtonTextBox等)的登录表单。 基本上这就是它的完成方式:{​​{3}}

但有一个问题。叠加层应填充可用空间。因此,我将表单面板的Vertical- / HorizontalAlignment属性(ControlAdorner的子项)设置为Stretch。但是,只需要显示Panel所需的空间,而不是使用整个可用空间。

我认为这就是原因:
使用正确的大小(可用空间)调用ControlAdorner方法MeasureOverride。但随后Child的Measure - 方法用于计算所需的大小。而这个调用似乎忽略了Stretch属性。可能是因为Child没有设置Parent,因为Child是动态生成的。

有没有办法实现这个Stretch - 让Adorner的孩子正常工作?

1 个答案:

答案 0 :(得分:0)

我得到了它的工作: - )

由于Adorner MeasureOverride已经计算出覆盖装饰元素的正确尺寸,因此我们不需要覆盖它。但是我们需要覆盖ArrangeOverride,因为我们需要调用孩子的Arrange方法。否则可能无法显示。

所以这是一个有效的示例代码:

<强> MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace AdornerTest {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e) {
            StackPanel overlayPanel = new StackPanel() {
                Background = new SolidColorBrush(Color.FromArgb(0x99, 0, 0, 0xFF)),
            };

            // example content 1
            Rectangle overlayChild1 = new Rectangle() {
                Fill = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)),
                Margin = new Thickness(10),
                Height = 50,
            };
            overlayPanel.Children.Add(overlayChild1);

            // example content 2
            Button overlayChild2 = new Button();
            overlayChild2.Content = "asdasd";
            overlayChild2.Margin = new Thickness(10);
            overlayPanel.Children.Add(overlayChild2);

            OverlayAdorner adorner = new OverlayAdorner(mainGrid) {
                Content = overlayPanel,
            };
            AdornerLayer.GetAdornerLayer(mainGrid).Add(adorner);
        }
    }


    class OverlayAdorner : Adorner {
        private FrameworkElement _content;

        public OverlayAdorner(UIElement adornedElement)
            : base(adornedElement) {
        }

        protected override int VisualChildrenCount {
            get {
                return _content == null ? 0 : 1;
            }
        }

        protected override Visual GetVisualChild(int index) {
            if (index != 0) throw new ArgumentOutOfRangeException();
            return _content;
        }

        public FrameworkElement Content {
            get { return _content; }
            set {
                if (_content != null) {
                    RemoveVisualChild(_content);
                }
                _content = value;
                if (_content != null) {
                    AddVisualChild(_content);
                }
            }
        }

        protected override Size ArrangeOverride(Size finalSize) {
            _content.Arrange(new Rect(new Point(0, 0), finalSize));
            return base.ArrangeOverride(finalSize);
        }
    }
}

<强> MainWindow.xaml

<Window x:Class="AdornerTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <AdornerDecorator>
        <Grid Name="mainGrid">
            <Button Content="Show Overlay" Name="button" VerticalAlignment="Top" Click="button_Click" />
        </Grid>
    </AdornerDecorator>
</Window>
相关问题