WPF 子窗打开时在父窗显示蒙板

 WPF 子窗打开时在父窗显示蒙板

控件名:WindowHelpers

作   者:WPFDevelopersOrg - 驚鏵

原文链接[1]:https://github.com/WPFDevelopersOrg/WPFDevelopers

  • 框架使用.NET40

  • Visual Studio 2022;

  • 使用方式需引入命名空间 using WPFDevelopers.Helpers;

    • new AboutWindow().MaskShowDialog();,即可显示蒙板,并 ShowDialog 开窗体。

    • new AboutWindow().MaskShow(); ,即可显示蒙板,并 MaskShow 开窗体。

1)创建装饰 AdornerContainer 代码如下:

using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace WPFDevelopers.Utilities
{
    public class AdornerContainer : Adorner
    {
        private UIElement _child;
        public AdornerContainer(UIElement adornedElement) : base(adornedElement)
        {
        }
        public UIElement Child
        {
            get => _child;
            set
            {
                if (value == null)
                {
                    RemoveVisualChild(_child);
                    _child = value;
                    return;
                }
                AddVisualChild(value);
                _child = value;
            }
        }
        protected override int VisualChildrenCount
        {
            get
            {
                return _child != null ? 1 : 0;
            }
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _child?.Arrange(new Rect(finalSize));
            return finalSize;
        }

        protected override Visual GetVisualChild(int index)
        {
            if (index == 0 && _child != null) return _child;
            return base.GetVisualChild(index);
        }
    }
}

2)创建蒙板控件 MaskControl 代码如下:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WPFDevelopers.Controls
{
    public class MaskControl : ContentControl
    {
        private readonly Visual visual;
        public static readonly DependencyProperty CornerRadiusProperty =
          DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(MaskControl), 
              new PropertyMetadata(new CornerRadius(0)));
        public MaskControl(Visual _visual)
        {
            visual = _visual;
        }
        public CornerRadius CornerRadius
        {
            get => (CornerRadius)GetValue(CornerRadiusProperty);
            set => SetValue(CornerRadiusProperty, value);
        }
    }
}

3)创建 WindowHelpers

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using WPFDevelopers.Controls;
using WPFDevelopers.Utilities;

namespace WPFDevelopers.Helpers
{
    public static class WindowHelpers
    {
        public static void MaskShow(this Window outputWindow)
        {
            CreateMask(outputWindow);
            outputWindow.Show();
        }
        public static bool? MaskShowDialog(this Window outputWindow)
        {
            CreateMask(outputWindow);
            return outputWindow.ShowDialog();
        }
        public static void CreateMask(this Window outputWindow)
        {
            Visual parent = null;
            if (Application.Current.Windows.Count > 0)
                parent = Application.Current.Windows.OfType<Window>().FirstOrDefault(o => o.IsActive);
            var _layer = GetAdornerLayer(parent);
            if (_layer == null) return;
            var _adornerContainer = new AdornerContainer(_layer)
            {
                Child = new MaskControl(parent)
            };
            _layer.Add(_adornerContainer);
            if (outputWindow != null)
            {
                outputWindow.Closed += delegate
                {
                    if (parent != null)
                        _layer.Remove(_adornerContainer);
                };
            }
        }
        static AdornerLayer GetAdornerLayer(Visual visual)
        {
            var decorator = visual as AdornerDecorator;
            if (decorator != null)
                return decorator.AdornerLayer;
            var presenter = visual as ScrollContentPresenter;
            if (presenter != null)
                return presenter.AdornerLayer;
            var visualContent = (visual as Window)?.Content as Visual;
            return AdornerLayer.GetAdornerLayer(visualContent ?? visual);
        }
    }
}

4)创建 MaskExample.xaml 示例代码如下:

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.MaskExample"
             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:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
             xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls"
             xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
        <Grid Margin="10">
           <StackPanel Orientation="Horizontal"
                    HorizontalAlignment="Center">
                <Button Content="MaskShowDialog" Click="Button_Click"/>
                <Button Content="MaskShowDialog" Margin="10,0" Click="Button_Click_1"/>
            </StackPanel>
        </Grid>
</UserControl>

5)创建 MaskExample.xaml.cs 示例代码如下:

using System.Windows.Controls;
using WPFDevelopers.Helpers;

namespace WPFDevelopers.Samples.ExampleViews
{
    /// <summary>
    /// MaskExample.xaml 的交互逻辑
    /// </summary>
    public partial class MaskExample : UserControl
    {
        public MaskExample()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            new AboutWindow().MaskShowDialog();
        }

        private void Button_Click_1(object sender, System.Windows.RoutedEventArgs e)
        {
            new AboutWindow().MaskShow();
        }
    }
}
e7874d18315910d6b6f5f4a1c194b52a.gif

参考资料

[1]

原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值