WPF 自定义MessageBox系列
第一节 简单MessageBox(本节)
第二节 倒计时MessageBox
第三节 自定义按钮的MessageBox
第四节 界面操作分离的MessageBox
第五节 替换系统的MessageBox
前言
在wpf中实现一个MessageBox很容易,但是还是要去编写的,如果每次新建不同的项目都重头编写一个MessageBox还是比较麻烦的,本文的目的是提供一个模板,用于快速实现一个MessageBox。
一、代码
1、MessageBox.xaml
<Window x:Class="WpfApp1.MessageBox"
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"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MessageBox"
AllowsTransparency="True"
Background="Transparent"
ResizeMode="NoResize"
ShowInTaskbar="False"
Topmost="True"
WindowStartupLocation="CenterScreen"
Width="600"
Height="260"
WindowStyle="None"
Closing="Window_Closing"
>
<Viewbox>
<Grid Width="600" Height="260">
<Border Margin="10" Background="White" >
<Border.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="10" Opacity="0.5"/>
</Border.Effect>
<Grid Margin="20">
<TextBlock x:Name="TB_Context" Margin="0,0,0,40" Text="Ensure?" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Foreground="Gray"/>
<Button VerticalAlignment="Bottom" Content="No" Tag="No" Margin="-174,0,0,0" Height="64" Width="144" Click="No_Button_Click" Cursor="Hand" >
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" Background="White" BorderBrush="#cccccc" >
<Border.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="10" Opacity="0.2"/>
</Border.Effect>
<TextBlock Text="{TemplateBinding Content}" FontSize="24" Foreground="Gray" HorizontalAlignment="Center" VerticalAlignment="Center">
</TextBlock>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button VerticalAlignment="Bottom" Content="Yes" Tag="Yes" Margin="174,0,0,0" Height="64" Width="144" Click="Yes_Button_Click" Cursor="Hand">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" Background="Gray" >
<Border.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="10" Opacity="0.2"/>
</Border.Effect>
<TextBlock Text="{TemplateBinding Content}" FontSize="24" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center">
</TextBlock>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Border>
</Grid>
</Viewbox>
</Window>
2、MessageBox.xaml.cs
using System;
using System.Windows;
namespace WpfApp1
{
public class MessageResult
{
/// <summary>
/// 结果,Yes为true,No为false
/// </summary>
public bool IsYes { get; set; }
}
public class MessageBoxEventArgs : EventArgs
{
/// <summary>
/// 结果,Yes为true,No为false
/// </summary>
public MessageResult Result { get; set; }
}
/// <summary>
/// MessageBox.xaml 的交互逻辑
/// </summary>
public partial class MessageBox : Window
{
public event EventHandler<MessageBoxEventArgs> Result;
public string Context
{
get { return TB_Context.Text; }
set { TB_Context.Text = value; }
}
bool _isLegal = false;
public MessageBox()
{
InitializeComponent();
}
public static void Show(string context, EventHandler<MessageBoxEventArgs> result)
{
var mb = new MessageBox();
mb.Context = context;
mb.Result += result;
mb.Show();
}
public static MessageResult ShowDialog(string context)
{
var mb = new MessageBox();
mb.Context = context;
MessageResult r=null;
mb.Result += (s,e)=> {
r = e.Result;
};
mb.ShowDialog();
return r;
}
private void No_Button_Click(object sender, RoutedEventArgs e)
{
_isLegal = true;
Close();
Result?.Invoke(this, new MessageBoxEventArgs() { Result = new MessageResult() { IsYes=false } });
}
private void Yes_Button_Click(object sender, RoutedEventArgs e)
{
_isLegal = true;
Close();
Result?.Invoke(this, new MessageBoxEventArgs() { Result = new MessageResult() { IsYes = true} });
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = !_isLegal;
}
}
}
二、效果预览
三、调用方法
异步
MessageBox.Show("Ensure?", (s, e) =>
{
if (e.Result.IsYes)
{
//选择了Yes
}
else
{
//选择了No
}
});
同步
var r = MessageBox.ShowDialog("Ensure?");
if (r.IsYes)
{
//选择了Yes
}
else
{
//选择了No
}
总结
本模板定义了Show方法,这是一个异步方法,显示MessageBox后不会堵塞,结果通过Result事件获取。