zoukankan      html  css  js  c++  java
  • 模拟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的代码基础之上,我加入的一些功能:

    1. 关闭按钮:
      在MessageBoxModule中定义关闭命令的依赖项属性: 
      1 /// <summary>
      2 /// 关闭命令
      3 /// </summary>
      4 public static readonly DependencyProperty CloseCommandProperty =
      5     DependencyProperty.Register(
      6         "CloseCommand", 
      7         typeof(RoutedCommand), 
      8         typeof(MessageBoxModule));
      1 /// <summary>
      2 /// 关闭命令
      3 /// </summary>
      4 public RoutedCommand CloseCommand
      5 {
      6     get { return (RoutedCommand)GetValue(CloseCommandProperty); }
      7     set { SetValue(CloseCommandProperty, value); }
      8 }

      设置方法:

       1 /// <summary>
       2 /// 设置关闭窗口命令
       3 /// </summary>
       4 private void SetupCloseCommand()
       5 {
       6     InputGestureCollection inputGestures = 
       7         new InputGestureCollection();
       8     inputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt));
       9 
      10     CloseCommand = new RoutedCommand(
      11         "CloseCommand",
      12         typeof(MessageBoxModule),
      13         inputGestures);
      14 
      15     CommandBindings.Add(
      16         new CommandBinding(CloseCommand, CloseCommandExecuted));
      17 }

      在public MessageBoxModule()方法中调用即可。
      在MessageBoxModule的Style文件中对该命令的使用:

      <Button x:Name="CloseButton" Command="{TemplateBinding CloseCommand}" .../>
    2. 通过标题栏拖动MessageBox:
      之前写过的无边框的Windows窗体都是通过Rectangle的MouseLeftButtonDown事件来触发拖动窗体的,然后这个方法在这边行不通,于是又用这方法,还是行不通: 
      1 <i:Interaction.Triggers>
      2     <i:EventTrigger EventName="MouseLeftButtonDown">
      3         <i:InvokeCommandAction Command="{TemplateBinding DragOverCommand}"/>
      4     </i:EventTrigger/>
      5 </i:Interaction.Triggers>

      无意间看到《WPF编程宝典 C# 2010版》第18章中的无外观控件代码中的TemplatePart。照猫画虎地写下了以下代码:
      在Style文件中:

      <Rectangle x:Name="PART_TitleRectangle" .../>

      在MessageBoxModule类中:
      在类前面加上:

      1 [TemplatePart(Name="PART_TitleRectangle", Type=typeof(Rectangle))]
      2 internal sealed class MessageBoxModule : Window
      3 { }

      重载public void OnApplyTemplate()方法:

       1 public override void OnApplyTemplate()
       2 {
       3     base.OnApplyTemplate();
       4 
       5     // 为TitleRectangle添加MouseLeftButtonDown事件处理程序
       6     Rectangle rect = GetTemplateChild("PART_TitleRectangle") as Rectangle;
       7     if (rect != null)
       8     {
       9         rect.MouseLeftButtonDown += (sender, e) => { DragMove(); };
      10     }
      11 }
    3. 显示详细信息:
      主要是Style中几个相关控件的Visibility的设置,依据是MessageBoxModule类中的指定值,即DependencyProperty MessageDetailProperty是否为空来选择是否启用显示相信信息功能:
       1 <DockPanel x:Name="RootLayoutPanel">
       2     ...
       3     <Separator Visibility="{Binding Path=Visibility, ElementName=MessageDetailTextBlock}" DockPanel.Dock="Bottom"/>
       4     <!--信息区-->
       5     <DockPanel x:Name="ContentDockPanel" DockPanel.Dock="Top">
       6         ...
       7         <TextBlock x:Name="MessageTextBlock" Text="{TemplateBinding Message}"  DockPanel.Dock="Top" />
       8         <Grid Visibility="{Binding Path=IsChecked, ElementName=DetailInfoToggleButton, Converter={converter:BooleanToVisibilityConverter}}" >
       9             <TextBlock x:Name="MessageDetailTextBlock" 
      10                 Text="{TemplateBinding MessageDetail}" 
      11                 Visibility="{TemplateBinding MessageDetail, Converter={converter:StringToVisibilityConverter}}" 
      12                 DockPanel.Dock="Bottom" />
      13         </Grid>
      14     </DockPanel>
      15 </DockPanel>
    4. 加入MessageBoxImage:
      通过MessageBoxModule类中的DependencyProperty MessageBoxIconTypeProperty来指定显示哪种类型的图片: 
      1 /// <summary>
      2 /// 消息框图标
      3 /// </summary>
      4 public static readonly DependencyProperty MessageBoxIconTypeProperty =
      5     DependencyProperty.Register(
      6         "MessageBoxIconType",
      7         typeof(MessageBoxIcon),
      8         typeof(MessageBoxModule),
      9         new PropertyMetadata(MessageBoxIcon.None));

      MessageBoxIcon是枚举类型类似于MessageBoxImage的一个枚举类型:

       1 /// <summary>
       2 /// 图标
       3 /// </summary>
       4 public enum MessageBoxIcon
       5 {
       6     None = 0,
       7     Error = 0x10,
       8     //Hand = 0x10,
       9     //Stop = 0x10,
      10     Question = 0x20,
      11     Warning = 0x30,
      12     //Exclamation = 0x30,
      13     //Asterisk = 0x40,
      14     //Information = 0x40,
      15 }

      在Style文件中:

      1 <!--信息区-->
      2 <DockPanel x:Name="ContentDockPanel" DockPanel.Dock="Top" Margin="15,10">
      3     <Image x:Name="MB_MistakeImage" Visibility="Collapsed" Source="/Controls;component/Images/messagebox_mistake.png"/>
      4     <Image x:Name="MB_QueryImage" Visibility="Collapsed" Source="/Controls;component/Images/messagebox_query.png"/>
      5     <Image x:Name="MB_WarningImage" Visibility="Collapsed" Source="/Controls;component/Images/messagebox_warning.png"/>
      6     ...
      7 </DockPanel>

      用ControlTemplate.Triggers进行控制对应Image的Visibility属性:

       1 <ControlTemplate.Triggers>
       2     <Trigger Property="MessageBoxIconType" Value="Error">
       3         <Setter Property="Visibility" TargetName="MB_MistakeImage" Value="Visible"/>
       4     </Trigger>
       5     <Trigger Property="MessageBoxIconType" Value="Question">
       6         <Setter Property="Visibility" TargetName="MB_QueryImage" Value="Visible"/>
       7     </Trigger>
       8     <Trigger Property="MessageBoxIconType" Value="Warning">
       9         <Setter Property="Visibility" TargetName="MB_WarningImage" Value="Visible"/>
      10     </Trigger>
      11 </ControlTemplate.Triggers>

    【END】

  • 相关阅读:
    使用servletContext和类加载器加载文件
    servletConfig和servletContext的应用
    java中的正则表达式(一)
    servlet的生命周期
    servlet的基本原理
    java中类加载机制
    java中的动态代理(三)
    Navicat Premium 连接Oracle 数据库
    使用SqlServer2005 Service Broker 和 SqlDependency类提供数据更改的通知
    WebService简单使用
  • 原文地址:https://www.cnblogs.com/submarinex/p/3965700.html
Copyright © 2011-2022 走看看