WPF实现背景透明磨砂,并通过HandyControl组件实现弹出等待框
原文:WPF实现背景透明磨砂,并通过HandyControl组件实现弹出等待框

前言:上一个版本的Winform需要改成WPF来做界面,第一次接触WPF,在转换过程中遇到的需求就是一个背景透明模糊,一个是类似于 加载中…… 这样的等待窗口,等后台执行完毕后再关掉。在Winform中是通过一个类指定等待窗口的parent为调用者,并指定topmost为最顶层来实现。在WPF中这个方法不太灵光,通过这几天的摸索,找到一个WPF下的UI利器--HandyControl(https://github.com/HandyOrg/HandyControl)感谢作者分享。通过它来实现一些界面的效果,它里面带的有个顶部弹出对话框的功能(带遮罩),但这个不支持后台关闭(作者说是可以调用带回调的模式,但没有找到,也没有明确说明是哪个)。所以我就单独从里面把这个功能提取出来,实现了弹出提示框,后台可以关闭的模式。

先看一下HandyControl提供的Demo中的这种对话框。

由于我需要的是弹出后,后台会执行代码,代码执行完后主动关闭对话框的操作。于是我把里面的这块代码单独提取出来改造了一下,实现效果如下。

这是在新接触WPF开发中,学习到的,如何让主窗体背景磨砂透明、如何Grid背景透明模糊、如何让Grid的控件不随Grid来模糊。

下面进入代码:

首先新建一个WPF项目,然后通过Nuget引用HandyControl。

在App.xaml中添加以下内容,来引用HandyControl的样式效果。

    <Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary><ResourceDictionary><viewModel:ViewModelLocator x:Key="Locator" /></ResourceDictionary></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>

  添加一个类文件BlurBehind.cs,用来实现主窗体透明磨砂感。

using System;
using System.Runtime.InteropServices;namespace WpfApp1
{/// <summary>/// 背景磨砂/// </summary>public class BlurBehind{internal enum AccentState{ACCENT_DISABLED = 1,ACCENT_ENABLE_GRADIENT = 0,ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,ACCENT_ENABLE_BLURBEHIND = 3,ACCENT_INVALID_STATE = 4,ACCENT_ENABLE_ACRYLICBLURBEHIND = 5}[StructLayout(LayoutKind.Sequential)]internal struct AccentPolicy{public AccentState AccentState;public int AccentFlags;public int GradientColor;public int AnimationId;}[StructLayout(LayoutKind.Sequential)]internal struct WindowCompositionAttributeData{public WindowCompositionAttribute Attribute;public IntPtr Data;public int SizeOfData;}internal enum WindowCompositionAttribute{// ...WCA_ACCENT_POLICY = 19// ...}}
}

然后新建两个目录:ViewModel和Images

在Images中放入一张图片,并设置生成时自动复制

在ViewModel中新建三个类文件

DialogDemoViewModel.cs 用来实现弹出框

using System;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using HandyControl.Controls;namespace WpfApp1.ViewModel
{public class DialogDemoViewModel : ViewModelBase{private string _dialogResult;public string DialogResult{get => _dialogResult;
#if netle40set => Set(nameof(DialogResult), ref _dialogResult, value);
#elseset => Set(ref _dialogResult, value);
#endif}public RelayCommand<TextDialog> ShowTextCmd => new Lazy<RelayCommand<TextDialog>>(() =>new RelayCommand<TextDialog>(ShowText)).Value;private static void ShowText(TextDialog d){Dialog.Show(d);//获得句柄//var dialogShow = Dialog.Show(d);//var dialogShowHwnd = (HwndSource)PresentationSource.FromVisual(dialogShow);//if (dialogShowHwnd == null) return;//var hwnd = dialogShowHwnd.Handle;}}
}

  DialogInfo.cs 用来实现数据绑定给弹出框,比如指定显示文字

using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.ComponentModel;namespace WpfApp1.ViewModel
{public class DialogInfo : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;public DialogInfo(){MyTxt = "加载中,请稍后。";}private string myTxt;public string MyTxt{get => myTxt;set{myTxt = value;PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyTxt"));}}}
}

  ViewModelLocator.cs用来实现构建弹出框实例

using System;
using System.Windows;
using CommonServiceLocator;
using GalaSoft.MvvmLight.Ioc;namespace WpfApp1.ViewModel
{public class ViewModelLocator{public ViewModelLocator(){ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);SimpleIoc.Default.Register<DialogDemoViewModel>();}public static ViewModelLocator Instance => new Lazy<ViewModelLocator>(() =>Application.Current.TryFindResource("Locator") as ViewModelLocator).Value;#region Vmpublic DialogDemoViewModel DialogDemo => ServiceLocator.Current.GetInstance<DialogDemoViewModel>();#endregion}
}

  MainWindow.xaml 主窗体的内容

<Windowxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"x:Class="WpfApp1.MainWindow"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"DataContext="{Binding DialogDemo,Source={StaticResource Locator}}"Loaded="MainWindow_OnLoaded"Background="#727A7A7A"AllowsTransparency="True"WindowStyle="None"MouseDown="MainWindow_OnMouseDown" ><Grid HorizontalAlignment="Left" Height="397" Margin="10,10,0,0" VerticalAlignment="Top" Width="790" ZIndex="0" ><Grid Margin="0,10,10,97"><Grid.Background><ImageBrush ImageSource="/WpfApp1;component/Images/wow_cataclysm_artwork-wallpaper-960x540.jpg"></ImageBrush></Grid.Background><Grid.Effect><BlurEffect Radius="8"></BlurEffect></Grid.Effect></Grid><Button x:Name="Btn_Show" Content="Button" HorizontalAlignment="Left" Margin="430,185,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"  /><TextBlock x:Name="txtBlock" HorizontalAlignment="Left" Margin="614,120,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="120" Width="145" Foreground="White"/></Grid>
</Window>

  MainWindow.xaml.cs

using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Timers;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using WpfApp1.ViewModel;
namespace WpfApp1
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow {[DllImport("user32.dll")]private static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref BlurBehind.WindowCompositionAttributeData data);private uint _blurOpacity;public double BlurOpacity{get { return _blurOpacity; }set { _blurOpacity = (uint)value; EnableBlur(); }}private uint _blurBackgroundColor = 0x990000; /* BGR color format */public MainWindow(){InitializeComponent();} private void Button_Click(object sender, RoutedEventArgs e){var newWindow = new TextDialog();var dialog = new DialogDemoViewModel();if (dialog.ShowTextCmd.CanExecute(newWindow)){dialog.ShowTextCmd.Execute(newWindow);} newWindow.info.MyTxt="加载中";//if (DataContext is DialogDemoViewModel MyVM && MyVM.ShowTextCmd.CanExecute(newWindow))//    MyVM.ShowTextCmd.Execute(newWindow);var i = 0;var timer = new Timer(1000);timer.Elapsed+=delegate{Dispatcher.BeginInvoke(new Action(() =>{ if (i < 5){txtBlock.Text +=$"{5 - i}秒后关闭"+ Environment.NewLine;i++;}else{newWindow.CloseMe();}}));};timer.AutoReset = true;timer.Enabled = true;}/// <summary>///     获取当前应用中处于激活的一个窗口/// </summary>/// <returns></returns>private static Window GetActiveWindow() => Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);private void MainWindow_OnLoaded(object sender, RoutedEventArgs e){EnableBlur();}private void EnableBlur(){var windowHelper = new WindowInteropHelper(this);var accent = new BlurBehind.AccentPolicy{AccentState = BlurBehind.AccentState.ACCENT_ENABLE_BLURBEHIND,//GradientColor = (int) ((_blurOpacity << 24) | (_blurBackgroundColor & 0xFFFFFF))};var accentStructSize = Marshal.SizeOf(accent);var accentPtr = Marshal.AllocHGlobal(accentStructSize);Marshal.StructureToPtr(accent, accentPtr, false);var data = new BlurBehind.WindowCompositionAttributeData{Attribute = BlurBehind.WindowCompositionAttribute.WCA_ACCENT_POLICY,SizeOfData = accentStructSize,Data = accentPtr};SetWindowCompositionAttribute(windowHelper.Handle, ref data);Marshal.FreeHGlobal(accentPtr);}private void MainWindow_OnMouseDown(object sender, MouseButtonEventArgs e){if (e.ChangedButton == MouseButton.Left)DragMove();}}}

  TextDialog.xaml 对话框

<Border x:Class="WpfApp1.TextDialog"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:hc="https://handyorg.github.io/handycontrol"CornerRadius="10"Width="400"Height="247"Background="{DynamicResource RegionBrush}"><hc:SimplePanel><TextBlock x:Name="TextBlock" Style="{StaticResource TextBlockLargeBold}" Text="{Binding MyTxt,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="100,0,0,119" VerticalAlignment="Bottom" Height="68" Width="100"/><Button x:Name="BtnClose" Width="22" Height="22" Command="hc:ControlCommands.Close" Style="{StaticResource ButtonIcon}" Foreground="{DynamicResource PrimaryBrush}" hc:IconElement.Geometry="{StaticResource ErrorGeometry}" Padding="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,4,4,0" Visibility="Hidden" /></hc:SimplePanel>
</Border>

  TextDialog.xaml.cs 新增了一个CloseMe 用来后台调用关闭它

using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using WpfApp1.ViewModel;namespace WpfApp1
{/// <summary>/// TextDialog_.xaml 的交互逻辑/// </summary>public partial class TextDialog{public DialogInfo info = new DialogInfo { MyTxt = "加载中……" };public TextDialog(){DataContext = info;InitializeComponent(); }public void CloseMe(){var bam = new ButtonAutomationPeer(BtnClose);var iip = bam.GetPattern(PatternInterface.Invoke) as IInvokeProvider;iip?.Invoke();}}
}

  

posted on 2019-06-27 23:09 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/11100215.html

WPF实现背景透明磨砂,并通过HandyControl组件实现弹出等待框相关推荐

  1. wpf 点击按钮弹出选择框_WPF-PopupWindow wpf右下角弹出框,通过按钮调用,类似QQ CSharp C#编程 238万源代码下载- www.pudn.com...

    文件名称: WPF-PopupWindow下载 收藏√  [ 5  4  3  2  1 ] 开发工具: C# 文件大小: 90 KB 上传时间: 2013-07-24 下载次数: 19 详细说明:w ...

  2. wpf 点击按钮弹出选择框_关于WPF的弹出窗口

    几个重要的概念需要清楚: Show和ShowDialog区别 1.调用Show方法后弹出子窗口后,线程会继续往下执行.调用ShowDialog方法弹出子窗口后,线程会阻塞,直到子窗口关闭才继续往下执行 ...

  3. 透明设置Android:将activity设置为弹出式的并设置为透明的

    首先声明,我是一个菜鸟.一下文章中出现技术误导情况盖不负责 1. 在res/values 下建立color.xml <resources><colorname="trans ...

  4. wpf 代码获取contextmenu_WPF 如何控制右键菜单ContextMenu的弹出

    在具体做一些项目的时候,有时候需要需要先左键点击某个节点,然后再右键点击节点的时候才弹出右键菜单,所以直接右键点击时需要禁用掉右键菜单,这里比如我们为Grid添加了ContextMenu,但是我们需要 ...

  5. WPF MVVM 弹框之等待框

    WPF MVVM 弹框之等待框 目录 一.效果 二.弹框主体改造 三.等待动画用户控件 四.弹窗 ViewModel 和帮助类的改造 五.使用方法和代码地址 独立观察员 2020年10月13日 之前写 ...

  6. WPF的WebBrowser屏蔽弹出脚本错误窗口

    WPF中使用System.Windows.Controls.WebBrowser时脚本错误会弹出提示框,但这个WebBrowser没有提供类似System.Windows.Forms.WebBrows ...

  7. 底部弹出PopupWindow并且背景变为半透明效果

    来自:http://blog.csdn.net/LANG791534167/article/details/48985101 先来看看运行效果图 [方式一]实现从底部弹出PopupWindow 原理: ...

  8. wpf 代码获取contextmenu_[C#] 转:在WPF里面获取右键弹出菜单(ContextMenu)的鼠标点击源(Owner)控件...

    WPF的ContextMenu没有类似WinForm里面ContextMenu.SourceControl的概念,但是你可以通过ContextMenuService的GetPlacementTarge ...

  9. html 原生弹出框,html、css和js原生写一个模态弹出框,顺便解决父元素半透明子元素不透明效果...

    模态框: html部分: 弹出框 hhhhh 取消 确认 css部分: #box{ width: 80px; height: 40px; background: #fd7430; border:non ...

最新文章

  1. 无法启动python怎么办_解决python写的windows服务不能启动的问题
  2. 超效率dea模型_【探索】基于超效率DEA模型的我国公立医院排行榜研究
  3. Java AOP研究之@Aspect注解的工作原理
  4. 超级全面的权限系统设计方案
  5. android 监听安装来源_Flutter插件开发之APK自动安装
  6. Tensorflow快餐教程(4) - 矩阵
  7. Java:根据字节数截取字符串,但是汉字不能截取半个。
  8. (转载)委托与函数指针辨析
  9. 设计资源类的网站有哪些?
  10. 转换成的jar文件接收后台的信息乱码cmd解决办法
  11. python获取请求中的参数_python – 在Tastypie中获取请求参数
  12. android listview 只加载显示的图片大小,Android ListView只加载当前屏幕内的图片(解决list滑动时加载卡顿)...
  13. 多行文字省略(涵盖标点符号,中英文等复杂字符串)
  14. 为什么C与C++执行效率高,运行快?
  15. f5计算机中代表什么,ctrl f5是什么意思
  16. python --通过urlretrieve下载MP4文件
  17. YOLOV3 config理解
  18. Unity PBR材质
  19. 利用计算机本地文档重装系统,电脑如何用本地模式重装win10
  20. 水文专业对计算机要求,来了来了,高考志愿这么填!

热门文章

  1. [转]JavaScript优化方案
  2. restful规范和APIView
  3. [JZOJ5863] 【NOIP2018模拟9.11】移动光标
  4. BZOJ3123: [Sdoi2013]森林
  5. Mac Sublime Vim模式 方向键无法长按
  6. ADB server didn't ACK的解决方法
  7. 学习NodeJS第一天:node.js引言
  8. [NOTE]常用Linux命令总结[Thx for commandlinefu]
  9. 移动客户端与服务器端安全通信方案
  10. C++入门课程系列:基础知识篇(1)