您好,登錄后才能下訂單哦!
這篇文章主要講解了“基于WPF如何實(shí)現(xiàn)蒙板控件”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“基于WPF如何實(shí)現(xiàn)蒙板控件”吧!
WPF 實(shí)現(xiàn)蒙板控件
框架使用.NET40
;
Visual Studio 2022
;
使用方式需引入命名空間后 wd:Mask.IsMask="true"
,即可顯示蒙板。
顯示蒙板內(nèi)容需 wd:Mask.Child
進(jìn)行復(fù)賦值。
實(shí)現(xiàn)代碼
1)創(chuàng)建裝飾 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)創(chuàng)建蒙板控件 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)創(chuàng)建 Mask
繼承 Control
增加附加屬性 IsMask
代碼如下:
True
則動態(tài)添加裝飾器 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)創(chuàng)建 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)創(chuàng)建 MaskExample.xaml
實(shí)例代碼如下:
<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如何實(shí)現(xiàn)蒙板控件”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對基于WPF如何實(shí)現(xiàn)蒙板控件這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。