系统环境
本程序基于.net4.0,引入了mvvmlight轻量级框架。
Dialog类库
Dialog类库中包含3个文件
1.DialogView:
DialogView是一个自定义用户控件,在一个Grid中包含了2个Border:
第一个Border用于遮罩modal Dialog后面的地方
第二个Border是显示内容的地方将配置
VerticalAlignment="Center" HorizontalAlignment="Center"
使得显示内容居中在此Border中通过2层border实现了Dialog的圆角效果。
在内层Border内定义一个Grid,Grid拆分成2个Row,第一个Row中设置Title及关闭按钮;第二个Row显示被设置的窗体内容。
窗体内容为一个ContentControl通过DataBind来显示填充窗体内容。具体代码如下:
<Grid Visibility="{Binding Visibility}"> <Border Background="White" Opacity="{Binding Opcity}"></Border> <Border VerticalAlignment="Center" HorizontalAlignment="Center"> <Border BorderThickness="1" BorderBrush="#34629E" Width="{Binding Width}" Height="{Binding Height}" CornerRadius="3"> <Border BorderThickness="1" BorderBrush="#9ACAFF" Background="#DAE7FA" CornerRadius="3"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="25"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <DockPanel Background="#057ABB" Grid.Row="0"> <Button DockPanel.Dock="Right" Margin="0,-8, 10, 0" Command="{Binding CloseCommand}"> <Button.Style> <Style TargetType="Button"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Image Source="/Resources/Images/Dialog_Base_Close_Over.png" Width="46" Height="19" DockPanel.Dock="Right" > </Image> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> <Setter Property="FocusVisualStyle"> <Setter.Value> <Style></Style> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Image Source="/Resources/Images/Dialog_Base_Close_Normal.png" Width="46" Height="19" DockPanel.Dock="Right" > </Image> </ControlTemplate> </Setter.Value> </Setter> </Style> </Button.Style> </Button> <Border VerticalAlignment="Center" DockPanel.Dock="Left"> <Image Source="/Resources/Images/Dialog_Title.png" Width="18" Height="13" Margin="5,0"></Image> </Border> <Border DockPanel.Dock="Left" VerticalAlignment="Center"> <TextBlock Text="{Binding Title}" Foreground="White" FontSize="13"></TextBlock> </Border> </DockPanel> <Grid Grid.Row="1"> <ContentControl Content="{Binding Content}"></ContentControl> </Grid> </Grid> </Border> </Border> </Border> </Grid>
2.DialogParam:
DialogParam中定义了窗体的5个基本属性
Opcity:控制透明度(0.0-1.0之间)
Title:窗体标题
Width:窗体宽度
Height:窗体高度
Content:窗体内容,为自定义ViewModel
public class DialogParam { public double Opcity { get; set; } public string Title { get; set; } public object Content { get; set; } public int Height { get; set; } public int Width { get; set; } }
3.DialogViewModel:
DialogViewModel包含了DialogParam中的窗体的基本属性,用于Dialog中的绑定
Visibility:控制是否显示窗体
在DialogViewModel中使用了MvvmLight中的消息机制。注册了2个消息用token “Dialog_Open” 和 “Dialog_Close” 区分。
打开窗口消息:传入DialogParam对象,设置窗口属性及内容。
关闭窗口消息:通知消息,设置窗体不可用,并将窗体正文dispose。
代码如下:
public class DialogViewModel : ViewModelBase, IDisposable { #region Properties private string _visibility = "Collapsed"; public string Visibility { set { _visibility = value; RaisePropertyChanged("Visibility"); } get { return _visibility; } } private double _opcity; private double _defaultOpcity = 0.5; public double Opcity { set { _opcity = value; RaisePropertyChanged("Opcity"); } get { return _opcity; } } private string _title { get; set; } public string Title { set { _title = value; RaisePropertyChanged("Title"); } get { return _title; } } private int _defaultWidth = 500; private int _defaultHeight = 300; private int _width; public int Width { set { _width = value; RaisePropertyChanged("Width"); } get { return _width; } } private int _height; public int Height { set { _height = value; RaisePropertyChanged("Height"); } get { return _height; } } private object _content { get; set; } public object Content { get { return _content; } set { _content = value; RaisePropertyChanged("Content"); } } #endregion public RelayCommand OKCommand { get; set; } public RelayCommand CloseCommand { get; set; } /// <summary> /// Initializes a new instance of the DialogViewModel class. /// </summary> public DialogViewModel() { //Messenger.Default.Send( Messenger.Default.Register<DialogParam>(this, Constants.Dialog_Open, m => { Visibility = "Visible"; Opcity = m.Opcity != 0 ? m.Opcity : _defaultOpcity; Height = m.Height != 0 ? m.Height : _defaultHeight; Width = m.Width != 0 ? m.Width : _defaultWidth; Title = m.Title; Content = m.Content; }); Messenger.Default.Register<NotificationMessage>(this, Constants.Dialog_Close, m => { Visibility = "Collapsed"; ((ViewModelBase)Content).Dispose(); }); CloseCommand = new RelayCommand(() => { Visibility = "Collapsed"; ((ViewModelBase)Content).Dispose(); }); } public void Dispose() { Messenger.Default.Unregister<NotificationMessage>(this); Messenger.Default.Unregister<DialogParam>(this); } }
测试窗体
1.主窗体
模式窗体处在窗口的最前面并遮罩其后面的所有内容,所以需要再主窗体MainWindow中增加DialogView并为其绑定DialogViewModel
<Grid> <vw:BoardView DataContext="{Binding Board}"></vw:BoardView> <dialogvw:DialogView DataContext="{Binding Dialog}"></dialogvw:DialogView> </Grid>
在MainViewModel中创建一个DialogViewModel对象,用于绑定DialogView及接收窗口消息。
2.两个测试窗体
定义两个测试窗口ADialogView和BDialogView,在其对应的ViewModel中定义保存和取消命令的响应方法,在保存命令的响应方法中触发保存事件并发出关闭按钮。而取消命令只发送保存按钮。
public class ADialogViewModel : ViewModelBase { public delegate void SaveHandler(); public event SaveHandler SaveEvent; public RelayCommand SaveCommand { get; set; } public RelayCommand CancelCommand { get; set; } /// <summary> /// Initializes a new instance of the ADialogViewModel class. /// </summary> public ADialogViewModel() { SaveCommand = new RelayCommand(() => { if (SaveEvent != null) { SaveEvent(); } Messenger.Default.Send<NotificationMessage>(new NotificationMessage(this, ""), Constants.Dialog_Close); }); CancelCommand = new RelayCommand(() => { Messenger.Default.Send<NotificationMessage>(new NotificationMessage(this, ""), Constants.Dialog_Close); }); } }
在资源文件中定义2个DataTemplate,DataType为ADialogViewModel和BDialogView,其内容分别为ADialog和BDialog:
<DataTemplate DataType="{x:Type dialogvm:ADialogViewModel}"> <dialogvw:ADialogView></dialogvw:ADialogView> </DataTemplate> <DataTemplate DataType="{x:Type dialogvm:BDialogViewModel}"> <dialogvw:BDialogView></dialogvw:BDialogView> </DataTemplate>
3.主界面
BoardView是程序主界面内容,包含于主窗体中,其内定义了2个Button用于触发打开窗口的消息,在其对应的BoardViewModel中定义了两个RelayCommand,在其响应事件中设置DialogParam并发送打开窗口的消息。
如下代码所示,在响应事件中注册了SaveEvent事件的方法并配置了窗体的显示参数,最后发出打开窗口的消息。
ShowACommand = new RelayCommand(() => { ADialogViewModel a = new ADialogViewModel(); a.SaveEvent += refreshBoardAfterA; DialogParam param = new DialogParam(); param.Content = a; param.Title = "A"; param.Height = 200; param.Width = 200; param.Opcity = 0.8; Messenger.Default.Send<DialogParam>(param, Constants.Dialog_Open); });
源码下载: