前言:上一个版本的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 netle40
set => Set(nameof(DialogResult), ref _dialogResult, value);
#else
set => 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 Vm
public DialogDemoViewModel DialogDemo => ServiceLocator.Current.GetInstance<DialogDemoViewModel>();
#endregion
}
}

  MainWindow.xaml 主窗体的内容

<Window
xmlns="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()
{
try
{
BtnClose.Visibility = Visibility.Visible;
BtnClose.OnClick();
}
catch
{
//
} }
}
/// <summary>
/// ButtonBase 扩展
/// </summary>
public static class ButtonBaseExtension
{
/// <summary>
/// 引发 <see>
/// <cref>Primitives.ButtonBase.Click</cref>
/// </see>
/// 路由事件。
/// </summary>
/// <param name="buttonBase">要引发路由事件的按钮</param>
public static void OnClick(this System.Windows.Controls.Primitives.ButtonBase buttonBase)
{
buttonBase.GetType().GetMethod(nameof(OnClick), BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(buttonBase, null);
}
} }

  

WPF实现背景透明磨砂,并通过HandyControl组件实现弹出等待框的更多相关文章

  1. WPF Windows背景透明其中的文字保持不透明

    原文:WPF Windows背景透明其中的文字保持不透明 版权声明:本文为博主原创,未经允许不得转载.交流.源码资料加群:161154103 https://blog.csdn.net/mpegfou ...

  2. android 透明弹出搜索框

    1.在QQ一些APP当中有是弹出一个半透明的搜索框的,其实这种效果就是很多种方法,自定义一个Dialog,或者直接将activity的背景变成半透明的也可以的. 下面就是将activity变成半透明的 ...

  3. 登录界面,body上有背景图,点击输入框时,弹出的手机键盘会把背景图顶变形,而且会把footer顶上去

    js: //防止背景图被手机键盘压缩变形 $(document).ready(function () { $('body').css({'height':$(window).height()}) }) ...

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

    模态框: html部分: <!-- 按钮 --> <button id="box" onclick="pop_box()">弹出框< ...

  5. WPF解决WindowsFormsHost背景透明

    项目案例:WPF使用WindowsFormsHost播放视频,视频上显示边框.字幕等特效: 难点问题 1.WindowsFormsHost不支持背景透明: 2.WPF Panel.ZIndex无效,W ...

  6. WPF Window背景半透明 ,蒙版操作实现

    原文:WPF Window背景半透明 ,蒙版操作实现 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/detail ...

  7. WPF通过不透明蒙板切割显示子控件

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Backspace110/article/ ...

  8. WPF 无边框透明窗体

    WindowStyle="None"--无边框,如果需要其它按钮,如缩小.放大.收缩.关闭按钮,可以自定义 AllowsTransparency="True"- ...

  9. 【原】CSS实现背景透明,文字不透明,兼容所有浏览器

    11.11是公司成立的日子,16岁啦,我呢3岁半,感谢公司给了这样一个平台,让我得以学习和成长,这里祝愿公司发展越来越好~ 进入主题,每年11月11号是光棍节,产生于校园,本来只是一流传于年轻人的娱乐 ...

随机推荐

  1. PHP mysqli_kill MySQLi 函数

    mysqli_kill - 让服务器杀掉一个 MySQL 线程 语法:mysqli_kill ( mysqli $link , int $processid ) 本函数可以用来让服务器杀掉 proce ...

  2. Tomcat安装、使用(Windows)

    一.下载.安装 1.下载 进官网下载 : https://tomcat.apache.org/ 选择自己适合的版本.在这里演示的是下载 Tomcat 7(解压安装版). 2.解压.启动tomcat 解 ...

  3. 解决vue中百度地图覆盖物引用本地图片问题

    这次的主要目的是在百度地图中引用自定义的覆盖物,路径是再asset/images/文件夹下,直接引用出错.需要先导入再引用. 在<script></script>代码中增加如下 ...

  4. 微信跳转外部浏览器下载app原理

    在我们使用微信营销的时候,很容易碰到推广连接在微信内无法打开或无法下载app的情况.通常这种情况微信会给个提示 “已停止访问该网址” ,那么导致这个情况的因素有哪些呢,主要有以下三点 1.网页链接被举 ...

  5. jQuery Migrate 插件用法

    jQuery Migrate是应用迁移辅助插件,是用于高级版本兼容低级版本辅助插件.例如jQuery版本用的是1.x,计划升级到3.x,就可以在页面删除1.x版本,换成3.x版本,如果有脚本错误,就引 ...

  6. MySQL数据篇(五)--SQL对数据进行按月统计,或对数据进行按星期统计

    对于所有的需求,当你不知道怎么处理的时候,你就先用最简单的方法,或者说的明白一点,用最原始的方法,先实现业务需求再说. 一.对提现队列数据表“ims_checkout_task”进行汇总统计,按月汇总 ...

  7. 大数据安全利器ranger 编译安装

    ranger大数据领域的一个集中式安全管理框架,它可以对诸如hdfs.hive.kafka.storm等组件进行细粒度的权限控制.本文将介绍部署过程 1.  部署准备 ranger:    进入apa ...

  8. Mysql Join-连接查询(中)

    Mysql Join-连接查询(中) 认识 就我平时的数据接触来看, 连接查询也没有很复杂,不够是非常需要耐心和逻辑的, 一点点将数据查出来, 拼接等. 没有什么技巧, 多练习就会了. 无非就是表之间 ...

  9. BayaiM__MYSQL千万级数据量的优化方法积累__初级菜鸟

      -----------------------------------------------------------------------------———————-------------- ...

  10. nginx在centos下的安装

    第一步:打开浏览器下载,再上传到centOS系统中 http://nginx.org/download/ 或者在 centOS系统输入: wget http://nginx.org/download/ ...