原文:《模擬MessageBox》 Posted on 2014/01/07html
================================================================================編程
這段時間在用WPF開發項目。界面採用的是相似Win8系統的Metro風格,可是系統自帶MessageBox貌似不能被Style,因而重寫MessageBox。windows
以前一直沒有寫過自定義控件,就不知道怎麼下手。因而從網上找了好些資料,發現了這篇博文《WPF 自定義 MessageBox (相對完善版)》。看了代碼解釋並運行了Demo,以爲根據實際須要改造下應該能夠用到項目裏來。ide
之前一直很好奇爲何能Style不少控件,而MessageBox卻不能Style,查過.NET Reflector,發現:spa
public sealed class MessageBox : System.Object
MessageBox類 是直接繼承自Object類,其實是對具體細節進行了封裝。code
整體結構創建在Vito.K的代碼基礎之上,我加入的一些功能:component
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 }
設置方法:orm
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文件中對該命令的使用:htm
<Button x:Name="CloseButton" Command="{TemplateBinding CloseCommand}" .../>
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文件中:blog
<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 }
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>
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】