• 实现wpf中模式对话框


    系统环境

    本程序基于.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);
                });

    源码下载:

    https://files.cnblogs.com/icestone/ModalDialogDemo.zip

  • 相关阅读:
    循环移位算法
    关于Java中2.0-1.1!=0.9的问题
    Java基础语法(三)
    Java基础语法(二)
    Java基础语法(一)
    关于Java运行机制
    Java从零开始(前篇)
    关于.ssh目录下的known_hosts文件的补充
    解决 bash cd too many arguments 报错
    Markdown学习笔记(一)
  • 原文地址:https://www.cnblogs.com/icestone/p/2266740.html
Copyright © 2020-2023  润新知