模拟MessageBox
原文:《模拟MessageBox》 Posted on 2014/01/07
================================================================================
这段时间在用WPF开发项目。界面采用的是类似Win8系统的Metro风格,但是系统自带MessageBox貌似不能被Style,于是重写MessageBox。
之前一直没有写过自定义控件,就不知道怎么下手。于是从网上找了好些资料,发现了这篇博文《WPF 自定义 MessageBox (相对完善版)》。看了代码解释并运行了Demo,觉得根据实际需要改造下应该可以用到项目里来。
以前一直很好奇为什么能Style很多控件,而MessageBox却不能Style,查过.NET Reflector,发现:
public sealed class MessageBox : System.Object
MessageBox类 是直接继承自Object类,实际上是对具体细节进行了封装。
总体结构建立在Vito.K的代码基础之上,我加入的一些功能:
- 关闭按钮:
在MessageBoxModule中定义关闭命令的依赖项属性:/// <summary>
/// 关闭命令
/// </summary>
public static readonly DependencyProperty CloseCommandProperty =
DependencyProperty.Register(
"CloseCommand",
typeof(RoutedCommand),
typeof(MessageBoxModule));/// <summary>
/// 关闭命令
/// </summary>
public RoutedCommand CloseCommand
{
get { return (RoutedCommand)GetValue(CloseCommandProperty); }
set { SetValue(CloseCommandProperty, value); }
}设置方法:
/// <summary>
/// 设置关闭窗口命令
/// </summary>
private void SetupCloseCommand()
{
InputGestureCollection inputGestures =
new InputGestureCollection();
inputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt)); CloseCommand = new RoutedCommand(
"CloseCommand",
typeof(MessageBoxModule),
inputGestures); CommandBindings.Add(
new CommandBinding(CloseCommand, CloseCommandExecuted));
}在public MessageBoxModule()方法中调用即可。
在MessageBoxModule的Style文件中对该命令的使用:<Button x:Name="CloseButton" Command="{TemplateBinding CloseCommand}" .../>
- 通过标题栏拖动MessageBox:
之前写过的无边框的Windows窗体都是通过Rectangle的MouseLeftButtonDown事件来触发拖动窗体的,然后这个方法在这边行不通,于是又用这方法,还是行不通:<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:InvokeCommandAction Command="{TemplateBinding DragOverCommand}"/>
</i:EventTrigger/>
</i:Interaction.Triggers>无意间看到《WPF编程宝典 C# 2010版》第18章中的无外观控件代码中的TemplatePart。照猫画虎地写下了以下代码:
在Style文件中:<Rectangle x:Name="PART_TitleRectangle" .../>
在MessageBoxModule类中:
在类前面加上:[TemplatePart(Name="PART_TitleRectangle", Type=typeof(Rectangle))]
internal sealed class MessageBoxModule : Window
{ }重载public void OnApplyTemplate()方法:
public override void OnApplyTemplate()
{
base.OnApplyTemplate(); // 为TitleRectangle添加MouseLeftButtonDown事件处理程序
Rectangle rect = GetTemplateChild("PART_TitleRectangle") as Rectangle;
if (rect != null)
{
rect.MouseLeftButtonDown += (sender, e) => { DragMove(); };
}
} - 显示详细信息:
主要是Style中几个相关控件的Visibility的设置,依据是MessageBoxModule类中的指定值,即DependencyProperty MessageDetailProperty是否为空来选择是否启用显示相信信息功能:<DockPanel x:Name="RootLayoutPanel">
...
<Separator Visibility="{Binding Path=Visibility, ElementName=MessageDetailTextBlock}" DockPanel.Dock="Bottom"/>
<!--信息区-->
<DockPanel x:Name="ContentDockPanel" DockPanel.Dock="Top">
...
<TextBlock x:Name="MessageTextBlock" Text="{TemplateBinding Message}" DockPanel.Dock="Top" />
<Grid Visibility="{Binding Path=IsChecked, ElementName=DetailInfoToggleButton, Converter={converter:BooleanToVisibilityConverter}}" >
<TextBlock x:Name="MessageDetailTextBlock"
Text="{TemplateBinding MessageDetail}"
Visibility="{TemplateBinding MessageDetail, Converter={converter:StringToVisibilityConverter}}"
DockPanel.Dock="Bottom" />
</Grid>
</DockPanel>
</DockPanel> - 加入MessageBoxImage:
通过MessageBoxModule类中的DependencyProperty MessageBoxIconTypeProperty来指定显示哪种类型的图片:/// <summary>
/// 消息框图标
/// </summary>
public static readonly DependencyProperty MessageBoxIconTypeProperty =
DependencyProperty.Register(
"MessageBoxIconType",
typeof(MessageBoxIcon),
typeof(MessageBoxModule),
new PropertyMetadata(MessageBoxIcon.None));MessageBoxIcon是枚举类型类似于MessageBoxImage的一个枚举类型:
/// <summary>
/// 图标
/// </summary>
public enum MessageBoxIcon
{
None = ,
Error = 0x10,
//Hand = 0x10,
//Stop = 0x10,
Question = 0x20,
Warning = 0x30,
//Exclamation = 0x30,
//Asterisk = 0x40,
//Information = 0x40,
}在Style文件中:
<!--信息区-->
<DockPanel x:Name="ContentDockPanel" DockPanel.Dock="Top" Margin="15,10">
<Image x:Name="MB_MistakeImage" Visibility="Collapsed" Source="/Controls;component/Images/messagebox_mistake.png"/>
<Image x:Name="MB_QueryImage" Visibility="Collapsed" Source="/Controls;component/Images/messagebox_query.png"/>
<Image x:Name="MB_WarningImage" Visibility="Collapsed" Source="/Controls;component/Images/messagebox_warning.png"/>
...
</DockPanel>用ControlTemplate.Triggers进行控制对应Image的Visibility属性:
<ControlTemplate.Triggers>
<Trigger Property="MessageBoxIconType" Value="Error">
<Setter Property="Visibility" TargetName="MB_MistakeImage" Value="Visible"/>
</Trigger>
<Trigger Property="MessageBoxIconType" Value="Question">
<Setter Property="Visibility" TargetName="MB_QueryImage" Value="Visible"/>
</Trigger>
<Trigger Property="MessageBoxIconType" Value="Warning">
<Setter Property="Visibility" TargetName="MB_WarningImage" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
【END】
模拟MessageBox的更多相关文章
- WPF 自定义 MessageBox (相对完善版)
WPF 自定义 MessageBox (相对完善版) 基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当 ...
- WPF 自定义 MessageBox (相对完善版 v1.0.0.6)
基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当你不得不弹出一个消息框通知用户消息时(虽然很不建议在程序中频繁 ...
- ASP.NET中MessageBox的实现
asp.net中没有MessageBox这个控件,固然可以插入Winform里的MessageBox,但一般不提倡,所以只能变通实现,主要有这几种方法: 1.直接利用javascript的alert和 ...
- C语言嵌入式系统编程修炼之四:屏幕操作
汉字处理 现在要解决的问题是,嵌入式系统中经常要使用的并非是完整的汉字库,往往只是需要提供数量有限的汉字供必要的显示功能.例如,一个微波炉的LCD上没有必要提供显示"电子邮件"的功 ...
- C语言嵌入式系统编程修炼
C语言嵌入式系统编程修炼 2008-08-19 作者:宋宝华 来源:天极网 C语言嵌入式系统编程修炼之背景篇 本文的讨论主要围绕以通用处理器为中心的协议处理模块进行,因为它更多地牵涉到具体的C语言编程 ...
- [读书笔记2]《C语言嵌入式系统编程修炼》
第3章 屏幕操作 3.1 汉字处理 现在要解决的问题是,嵌入式系统中经常要使用的并非是完整的汉字库,往往只是需要提供数量有限的汉字供必要的显示功能.例如,一个微波炉的LCD上没有必要提供显示&qu ...
- c# winform 自动关闭messagebox 模拟回车
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 一个简单的Webservice的demo,简单模拟服务
前段时间一直在学习WCF,匆匆忙忙的把<WCF全面解析>和<WCF服务编程>看了一遍,好多东西都不是很懂,又听了一下WCF分布式开发的网络教程,算是马马虎虎的明白点了.回顾了一 ...
- NetworkComms V3 模拟登陆
演示NetworkComms V3的用法 例子很简单 界面如下: 服务器端代码: 开始监听: //服务器开始监听客户端的请求 Connection.StartListening(ConnectionT ...
随机推荐
- Linux初学 - 安装及网络配置
安装版本 CentOS-6.4 虚拟机 vmware workstation 12 配置 网络配置 检查网络设置是否成功 如果网络配置文件检查没有问题,配置完成后网络仍然ping不同 1.检查虚拟机 ...
- Leetcode 204 Count Primes 数论
题意:统计小于n的质数个数. 作为一个无节操的楼主,表示用了素数筛法,并没有用线性素数筛法. 是的,素数筛法并不是该题最佳的解法,线性素数筛法才是. 至于什么是素数筛法,请百度吧. class Sol ...
- PHP之負載均衡下的session共用
最近忙於開發台灣運動彩券第四版的程式,所以已經很久沒有上來寫東西了,今天隨便寫點東西和大家分享. 首先說一下負載均衡,相信大家都知道負載均衡可以很好地解決網站大流量的問題,負載均衡就是把用戶的請求分發 ...
- 转:MPlayer源代码分析
一.Mplayer支持的格式 MPlayer是一个LINUX下的视频播放器,它支持相当多的媒体格式,无论在音频播放还是在视频播放方面,可以说它支持的格式是相当全面的. 视频格式支持:MPEG.AVI. ...
- linux环境内存分配原理 mallocinfo
Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...
- Mysql:Error Code 1235,This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决
This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决 这次国庆节回来后的测试中,在一个Mysql表达式 ...
- Android webView打不开网页的解决办法
在我们开发过程中,有可能会遇到webview有些网页打不开的问题.这可能是设置的不对,下面就是解决办法. 进行如下设置吧,大多数情况都能解决! displayWebview.getSettings() ...
- WindowsPhone-GameBoy模拟器开发四--Gameboy显示系统分析
这次说一下GB的显示系统,先从一幅Gb的内存分布图说起,请看图: 图中红色框框起来的部分就是这篇文章关注的部分,这一部分的内存地址从8000-9Fff,共8KB,这一部分是从来存储背景和游戏“精灵”的 ...
- mybatis热加载的实现
最近在使用mybatis,由于是刚刚开始用,用的并不顺手,目前是感觉有2个地方非常的不好用: 1.mybatis调试不方便 由于dao层只有接口,实现只是一个map的xml文件,想加断点都没有地方加, ...
- Linux Red hat修改主机名
步骤一:修改etc/hosts文件内容为 [root@kypt01 /]# cd etc[root@kypt01 etc]# cat hosts127.0.0.1 localhost kypt01 l ...