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](https://i-blog.csdnimg.cn/blog_migrate/2b345217484e7733bf7fa8fd28a86a5d.gif)
参考资料
[1]
原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers