• wpf 蒙版实现在控件或者窗口遮罩


    <Window x:Class="CommonUI.Control.Mask.Mask" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" WindowStyle="None"
            xmlns:local="clr-namespace:CommonUI.Control.Mask" mc:Ignorable="d" AllowsTransparency="True" Title="Mask"
            Height="450" Width="800" Background="Transparent" Activated="Window_Activated"
            Closed="Window_Closed" IsVisibleChanged="Window_IsVisibleChanged" LocationChanged="Window_LocationChanged">
        <Grid Background="#7F000000" MouseDown="container_MouseDown" Name="container" SizeChanged="Window_SizeChanged" >
        </Grid>
    </Window>
    
    
    
    using CommonUI.Control.Mask.Model;
    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Input;
    
    namespace CommonUI.Control.Mask
    {
        /// <summary>
        /// Mask.xaml 的交互逻辑
        /// </summary>
        public partial class Mask : Window
        {
            MaskConfig model;
    
            //父元素
            FrameworkElement uiElement;
    
            //自动定位
            DependencyPropertyDescriptor descriptor;
    
            /// <summary>
            /// 私有构造函数避免外部主动参与控制窗口
            /// </summary>
            /// <param name="config"></param>
            private Mask(FrameworkElement uiElement, MaskConfig config = null)
            {
                InitializeComponent();
                model = config;
    
                //绑定需要监听的事件
                Bind(uiElement);
    
                container.Children.Add(uiElement);
                InitWindow();
            }
    
            void Bind(FrameworkElement uiElement)
            {
                if (uiElement == null)
                {
                    return;
                }
                this.uiElement = uiElement;
            }
    
    
            /// <summary>
            /// 初始化
            /// </summary>
            private void InitWindow()
            {
                //Binding binding = new Binding
                //{
                //    Source = uiElement,
                //    Path = new PropertyPath(LeftProperty),
                //    Mode= BindingMode.TwoWay
                //};
                ////Control x;
                //this.SetBinding(LeftProperty, binding);
    
                if (model == null)
                {
                    return;
                }
                this.Title = model.Title;
    
                CalcPosition(model.Ownner);
            }
    
            /// <summary>
            /// 计算窗口定位
            /// </summary>
            /// <param name="parent"></param>
            void CalcPosition(FrameworkElement parent)
            {
                if (parent == null)
                {
                    this.WindowState = WindowState.Maximized;
                }
                else
                {
                    //获取窗口<0,0>坐标屏幕位置
                    var boundPoint = parent.PointToScreen(new Point(0, 0));
                    this.Left = boundPoint.X;
                    this.Top = boundPoint.Y;
                    this.Width = parent.ActualWidth;
                    this.Height = parent.ActualHeight;
                    AutoMoving(this.model.Ownner);
                }
            }
    
            /// <summary>
            /// 自动更新定位
            /// </summary>
            /// <param name="parent"></param>
            private void AutoMoving(FrameworkElement parent)
            {
                Window parentWindow = null;
                if (this.Owner is Window win)
                {
                    parentWindow = this.Owner;
    
                    if (!(this.model.Ownner is Window))
                    {
                        if (this.model.Ownner != null)
                        {
                            var point = this.model.Ownner.TranslatePoint(new(0, 0), (Window)this.Owner);
                            this.model.left = point.X;
                            this.model.top = point.Y;
    
                        }
                    }
    
                }
                if (parent is Window par)
                {
                    parentWindow = par;
                }
    
                //根据父窗口实时移动位置
                if (null != parentWindow && descriptor == null)
                {
                    descriptor = DependencyPropertyDescriptor.FromProperty(LeftProperty, typeof(Window));
                    //第一个对象为触发变化的对象
                    descriptor.AddValueChanged(parentWindow, (o, handle) =>
                    {
                        if (o is Window parentWindow)
                        {
                            this.Left = parentWindow.Left + this.model.left;
                            this.Top = parentWindow.Top + this.model.top;
                        }
                    });
                }
            }
    
            private void Window_Activated(object sender, EventArgs e)
            {
                if (this.IsActive)
                {
                    //this.WindowState = WindowState.Maximized;
                }
            }
    
            private void container_MouseDown(object sender, MouseButtonEventArgs e)
            {
                if (model == null)
                {
                    return;
                }
    
                //点击空白处关闭窗口
                if (model.ClickBlankCanClose)
                {
                    this.Close();
                }
            }
    
            /// <summary>
            /// 激活窗口(链式调用)
            /// </summary>
            public Mask ActiveWindow()
            {
                //激活已显示的窗口
                if (this.Visibility == Visibility.Visible)
                {
                    this.Activate();
                }
                else
                {
                    if (model == null)
                    {
                        this.Show();
                        return this;
                    }
                    //设置ownner
                    if (model.Ownner != null)
                    {
                        if (model.Ownner is Window parWindow)
                        {
                            this.Owner = parWindow;
                        }
                        else
                        {
                            var window = GetWindow(model.Ownner);
                            this.Owner = window;
                        }
                        CalcPosition(model.Ownner);
                    }
    
                    this.Owner.SizeChanged += Window_SizeChanged;
                    this.Owner.LocationChanged += Window_LocationChanged;
    
                    //根据配置控制是否打开模态框
                    if (model.ISModel)
                    {
                        this.ShowDialog();
                    }
                    else
                    {
                        this.Show();
                    }
                }
    
                return this;
            }
    
            /// <summary>
            /// 关闭窗口
            /// </summary>
            public void CloseWindow()
            {
                this.Close();
            }
    
            /// <summary>
            /// 构造蒙版对象
            /// </summary>
            /// <param name="uiElement">需要展示的ui组件</param>
            /// <param name="config">配置</param>
            /// <returns></returns>
            public static Mask Create(FrameworkElement uiElement, MaskConfig config = null)
            {
    
                return new Mask(uiElement, config);
            }
    
            private void Window_Closed(object sender, EventArgs e)
            {
                if (model == null)
                {
                    return;
                }
                model.CloseCallback?.Invoke();
            }
    
            private void Window_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
            {
                if (model == null)
                {
                    return;
                }
                if (e.NewValue is bool value)
                {
                    if (value)
                    {
                        AutoMoving(model.Ownner);
                    }
                    else
                    {
                        descriptor = null;
                    }
    
                }
    
    
                model.VisibilityChangeCallback?.Invoke(this.Visibility);
            }
    
            private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                CalcPosition(model.Ownner);
            }
    
            private void Window_LocationChanged(object sender, EventArgs e)
            {
                CalcPosition(model.Ownner);
            }
        }
    }
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    
    namespace CommonUI.Control.Mask.Model
    {
        public class MaskConfig
        {
            //如果父元素为非window时需要计算父级相对窗口的定位
            public double top;
            public double left;
    
            /// <summary>
            /// 任务栏显示的名称
            /// </summary>
            public string Title { get; set; } = "";
    
            /// <summary>
            /// 是否为模态
            /// </summary>
            public bool ISModel { get; set; } = false;
    
            /// <summary>
            /// 是否可以点击蒙版阴影位置关闭蒙版
            /// </summary>
            public bool ClickBlankCanClose { get; set; } = false;
    
            /// <summary>
            /// 相对父级
            /// </summary>
            public FrameworkElement Ownner { get; set; } = null;
    
            /// <summary>
            /// 关闭蒙版回调
            /// </summary>
            public Action CloseCallback { get; set; } = null;
    
            /// <summary>
            /// 窗口显示状态发生变化回调
            /// </summary>
            public Action<Visibility> VisibilityChangeCallback { get; set; } = null;
    
        }
    }
    
    
    留待后查,同时方便他人
    联系我:renhanlinbsl@163.com
  • 相关阅读:
    js 前端开发 编程 常见知识点笔记
    重置 PowerShell 和 cmd 设置 样式 为系统默认值 powershell windows10
    useMemo和useCallback的区别 及使用场景
    数组去重,利用 ES6 的 reduce() 方法 和 include 判断 实现
    Java 中 Lombok 的使用,提高开发速度必备
    记录 windows 系统常用的 CMD 命令
    React Native 的 FlatList 组件 实现每次滑动一整项(item)
    Spring------mysql读写分离
    Webservice与CXF框架快速入门
    quartz
  • 原文地址:https://www.cnblogs.com/ives/p/15161118.html
Copyright © 2020-2023  润新知