基于WPF实现蒙板控件的示例代码

Adelaide ·
更新时间:2024-09-20
· 849 次阅读

WPF 实现蒙板控件

框架使用.NET40

Visual Studio 2022;

使用方式需引入命名空间后 wd:Mask.IsMask="true",即可显示蒙板。

显示蒙板内容需 wd:Mask.Child 进行复赋值。

实现代码

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)创建 Mask 继承 Control 增加附加属性 IsMask 代码如下:

True 则动态添加装饰器 AdornerContainer 并将 MaskControl 添加到 AdornerContainer.Child 中。

False 则移除装饰器。

using System; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using WPFDevelopers.Helpers; using WPFDevelopers.Utilities; namespace WPFDevelopers.Controls {     public class Mask : Control     {         public object Child         {             get { return (object)GetValue(ChildProperty); }             set { SetValue(ChildProperty, value); }         }         public static readonly DependencyProperty ChildProperty =             DependencyProperty.Register("Child", typeof(object), typeof(Mask), new PropertyMetadata(null));         public static object GetChild(UIElement element)         {             if (element == null) { throw new ArgumentNullException("element"); }             return (object)element.GetValue(ChildProperty);         }         public static void SetChild(UIElement element, object child)         {             if (element == null) { throw new ArgumentNullException("element"); }             element.SetValue(ChildProperty, child);         }         public static readonly DependencyProperty IsMaskProperty =          DependencyProperty.RegisterAttached("IsMask", typeof(bool), typeof(Mask),              new PropertyMetadata(false, OnIsMaskChanged));         private static void OnIsMaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             PropertyChanged(d, e);         }         static void PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             if (e.NewValue is bool isMask && d is FrameworkElement parent)             {                 if (isMask)                 {                     if (!parent.IsLoaded)                         parent.Loaded += Parent_Loaded;                     else                         CreateMask(parent);                 }                 else                 {                     parent.Loaded -= Parent_Loaded;                     CreateMask(parent, true);                 }             }         }         private static void Parent_Loaded(object sender, RoutedEventArgs e)         {             if (sender is UIElement element)                 CreateMask(element);         }         static void CreateMask(UIElement uIElement, bool isRemove = false)         {             var _layer = AdornerLayer.GetAdornerLayer(uIElement);             if (_layer == null) return;             if (isRemove && uIElement != null)             {                 var adorners = _layer.GetAdorners(uIElement);                 if (adorners != null)                 {                     foreach (var item in adorners)                     {                         if (item is AdornerContainer container)                         {                             _layer.Remove(container);                         }                     }                 }                 return;             }             var _adornerContainer = new AdornerContainer(uIElement);             var value = Mask.GetChild(uIElement);              _adornerContainer.Child = new MaskControl(uIElement) { Content = value };             _layer.Add(_adornerContainer);         }         public static bool GetIsMask(DependencyObject obj)         {             return (bool)obj.GetValue(IsMaskProperty);         }         public static void SetIsMask(DependencyObject obj, bool value)         {             obj.SetValue(IsMaskProperty, value);         }     } }

4)创建 Mask.xaml 代码如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                     xmlns:controls="clr-namespace:WPFDevelopers.Controls">     <ResourceDictionary.MergedDictionaries>         <ResourceDictionary Source="Basic/ControlBasic.xaml"/>     </ResourceDictionary.MergedDictionaries>     <Style TargetType="{x:Type controls:MaskControl}" BasedOn="{StaticResource ControlBasicStyle}">         <Setter Property="HorizontalContentAlignment" Value="Center"/>         <Setter Property="VerticalContentAlignment" Value="Center"/>         <Setter Property="Background" Value="{DynamicResource PrimaryTextSolidColorBrush}"/>         <Setter Property="Template">             <Setter.Value>                 <ControlTemplate TargetType="{x:Type controls:MaskControl}">                     <controls:SmallPanel>                         <Border x:Name="PART_Border"                                         BorderBrush="{TemplateBinding BorderBrush}"                                          BorderThickness="{TemplateBinding BorderThickness}"                                          Background="{TemplateBinding Background}"                                         Height="{TemplateBinding Height}"                                          Width="{TemplateBinding Height}"                                         CornerRadius="{TemplateBinding CornerRadius}"                                         Opacity=".7"/>                         <ContentPresenter Margin="{TemplateBinding Padding}"                                                   VerticalAlignment="{TemplateBinding VerticalContentAlignment}"                                                   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>                     </controls:SmallPanel>                 </ControlTemplate>             </Setter.Value>         </Setter>     </Style> </ResourceDictionary>

5)创建 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>                 <ToggleButton Name="ToggleButtonMask"/>                 <Border Background="LawnGreen" Height="200"                     wd:Mask.IsMask="{Binding ElementName=ToggleButtonMask,Path=IsChecked}"                     Margin="10">                     <wd:Mask.Child>                         <Border>                             <TextBox wd:ElementHelper.IsWatermark="True"                                  wd:ElementHelper.Watermark="我是蒙板输入框"/>                         </Border>                     </wd:Mask.Child>                     <Button Content="Mask"                          VerticalAlignment="Center"                          HorizontalAlignment="Center"/>                 </Border>             </StackPanel>         </Grid> </UserControl>

效果图

以上就是基于WPF实现蒙板控件的示例代码的详细内容,更多关于WPF蒙板控件的资料请关注软件开发网其它相关文章!



wpf 示例

需要 登录 后方可回复, 如果你还没有账号请 注册新账号