系统环境
本程序基于.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);
});
源码下载: