csharp 自定义对话窗口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 自定义对话窗口相关的知识,希望对你有一定的参考价值。

using MvvmDialog1.View;
using MvvmDialog1.ViewModel.Interfaces;
using MvvmDialog1.ViewModel.Utils;
using MvvmDialog1.ViewModel.ViewModels;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace MvvmDialog1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            IDialogService dialogService = new DialogService(MainWindow);
            dialogService.Register<DialogWindowViewModel, ShowDialogWindow>();
            dialogService.Register<WindowViewModel, ShowWindow>();

            var viewModel = new MainWindowViewModel(dialogService);
            var view = new MainWindow { DataContext = viewModel };

            view.ShowDialog();
        }
    }
}
<Window x:Class="MvvmDialog1.View.ShowDialogWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStartupLocation="CenterScreen"
        Title="ShowDialogWindow" Height="190.036" Width="300">
    <Grid>
        <Button Content="OK" HorizontalAlignment="Left" 
                Margin="35,109,0,0" VerticalAlignment="Top" Width="75"
                Command="{Binding OkCommand}"/>
        <Button Content="Cancel" HorizontalAlignment="Left" Margin="159,109,0,0" 
                VerticalAlignment="Top" Width="75"
                Command="{Binding CancelCommand}"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="35,51,0,0" TextWrapping="Wrap" 
                 VerticalAlignment="Top" Width="199"
                 Text="{Binding Message}" />
    </Grid>
</Window>
<Window x:Class="MvvmDialog1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Open dialog window" HorizontalAlignment="Left" Margin="54,198,0,0" VerticalAlignment="Top" Width="139"
                Command="{Binding DisplayDialogWindow}"/>
        <Label Content="{Binding Message}" HorizontalAlignment="Left" Margin="54,120,0,0" VerticalAlignment="Top"/>
        
        <Button Content="Open window" HorizontalAlignment="Left" Margin="294,198,0,0" VerticalAlignment="Top" Width="139"
        	Command="{Binding DisplayWindow}"/>
        <Label Content="{Binding Message}" HorizontalAlignment="Left" Margin="294,120,0,0" VerticalAlignment="Top"/>

    </Grid>
</Window>
<Window x:Class="MvvmDialog1.View.ShowWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStartupLocation="CenterScreen"
        Title="ShowWindow" Height="190.036" Width="300">
    <Grid>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="36,59,0,0" TextWrapping="Wrap" 
                 Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                 VerticalAlignment="Top" Width="225"/>
        <Label Content="{Binding Message}" HorizontalAlignment="Left" Margin="36,10,0,0" 
               VerticalAlignment="Top"/>

    </Grid>
</Window>
using System.ComponentModel;

namespace MvvmDialog1.ViewModel.Utils
{
    abstract class BaseViewModel : INotifyPropertyChanged
    {
        protected void OnPropertyChanged(string property)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
using MvvmDialog1.ViewModel.Interfaces;
using MvvmDialog1.ViewModel.Utils;
using System;
using System.Windows.Input;

namespace MvvmDialog1.ViewModel.ViewModels
{
    class DialogWindowViewModel : IDialogRequestClose
    {
        public string Message { get; set; }

        /// <summary>
        /// Komenda zatwierdzająca (zwrócenie wyniku "prawda") i zamykająca okno.
        /// </summary>
        public ICommand OkCommand { get; private set; }

        /// <summary>
        /// Komenda zamykająca okno ze zwróceniem wyniku "fałsz".
        /// </summary>
        public ICommand CancelCommand { get; private set; }

        /// <summary>
        /// Domyślny konstruktor wymagany przez Xaml.
        /// </summary>
        public DialogWindowViewModel() { }

        /// <summary>
        /// Właściwy konstruktor stosowany przy tworzeniu instancji okna.
        /// </summary>
        /// <param name="message">Wiadomość wyświetlana w oknie. Zamiast tego mogą być jakiekolwiek inne zmienne.</param>
        public DialogWindowViewModel(string message)
        {
            this.Message = message;
            this.OkCommand = new RelayCommand(x => CloseRequested.Invoke(this, new DialogCloseRequestedEventArgs(true)));
            this.CancelCommand = new RelayCommand(x => CloseRequested.Invoke(this, new DialogCloseRequestedEventArgs(false)));
        }
        
        public event EventHandler<DialogCloseRequestedEventArgs> CloseRequested;
    }
}
using System.Windows;

namespace MvvmDialog1.ViewModel.Interfaces
{
    interface IDialog
    {
        object DataContext { get; set; }
        bool? DialogResult { get; set; }

        Window Owner { get; set; }
        void Close();

        bool? ShowDialog();
        void Show();
    }
}
using MvvmDialog1.ViewModel.Utils;
using System;

namespace MvvmDialog1.ViewModel.Interfaces
{
    interface IDialogRequestClose
    {
        event EventHandler<DialogCloseRequestedEventArgs> CloseRequested;
    }
}
namespace MvvmDialog1.ViewModel.Interfaces
{
    interface IDialogService
    {
        void Register<TViewModel, TView>()
            where TViewModel : IDialogRequestClose
            where TView : IDialog;

        bool? ShowDialog<TVIewModel>(TVIewModel viewModel) where TVIewModel : IDialogRequestClose;

        void Show<TVIewModel>(TVIewModel viewModel) where TVIewModel : IDialogRequestClose;
    }
}
using MvvmDialog1.ViewModel.Interfaces;
using MvvmDialog1.ViewModel.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace MvvmDialog1.ViewModel.ViewModels
{
    class MainWindowViewModel : BaseViewModel
    {
        string _message;
        readonly IDialogService _dialogService;

        public ICommand DisplayDialogWindow { get; private set; }
        public ICommand DisplayWindow { get; private set; }


        public string Message 
        { 
            get 
            { 
                return this._message; 
            } 
            set 
            {
                this._message = value;
                                
                this.OnPropertyChanged("Message"); 
            } 
        }

        public MainWindowViewModel() { }

        public MainWindowViewModel(IDialogService dialogService)
        {
            this._dialogService = dialogService;
            this.DisplayDialogWindow = new RelayCommand(x => displayMessage());
            this.DisplayWindow = new RelayCommand(x => display());
        }
        
        private void displayMessage()
        {
            var viewModel = new DialogWindowViewModel("Hello");
            bool? result = this._dialogService.ShowDialog(viewModel);

            if (result.HasValue)
            {
                if (result.Value)
                {
                    this.Message = viewModel.Message;
                    this.OnPropertyChanged("Message");
                }
                else
                {
                    this.Message = "Cancel";
                    this.OnPropertyChanged("Message");
                }
            }
        }

        private void display()
        {                                    
            var viewModel = new WindowViewModel("Hello");            
            this._dialogService.Show(viewModel);            
        }
    }
}
using System;

namespace MvvmDialog1.ViewModel.Utils
{
    class DialogCloseRequestedEventArgs : EventArgs
    {
        public bool? DialogResult { get; private set; }

        public DialogCloseRequestedEventArgs(bool? dialogResult)
        {
            this.DialogResult = dialogResult;
        }
    }
}
using MvvmDialog1.ViewModel.Interfaces;
using System;
using System.Collections.Generic;
using System.Windows;

namespace MvvmDialog1.ViewModel.Utils
{
    class DialogService : IDialogService
    {
        readonly Window _owner;

        public IDictionary<Type, Type> Mappings { get; set; }

        public DialogService(Window owner)
        {
            this._owner = owner;
            this.Mappings = new Dictionary<Type, Type>();
        }

        public void Register<TViewModel, TView>()
            where TViewModel : IDialogRequestClose
            where TView : IDialog
        {
            if (this.Mappings.ContainsKey(typeof(TViewModel)))
            {
                throw new ArgumentException("Type " + typeof(TViewModel) + " is already mapped to type " + typeof(TView));
            }

            this.Mappings.Add(typeof(TViewModel), typeof(TView));
        }

        public bool? ShowDialog<TViewModel>(TViewModel viewModel) where TViewModel : IDialogRequestClose
        {
            return getDialog<TViewModel>(viewModel).ShowDialog();
        }


        public void Show<TViewModel>(TViewModel viewModel) where TViewModel : IDialogRequestClose
        {
            getDialog<TViewModel>(viewModel).Show();
        }

        private IDialog getDialog<TViewModel>(TViewModel viewModel) where TViewModel : IDialogRequestClose
        {
            Type viewType = Mappings[typeof(TViewModel)];

            IDialog dialog = (IDialog)Activator.CreateInstance(viewType);

            EventHandler<DialogCloseRequestedEventArgs> handler = null;
            
            handler = (sender, e) =>
            {
                viewModel.CloseRequested -= handler;

                if (e.DialogResult.HasValue)
                {
                    dialog.DialogResult = e.DialogResult;
                }
                else
                {
                    dialog.Close();
                }
            };
            

            viewModel.CloseRequested += handler;

            dialog.DataContext = viewModel;

            dialog.Owner = _owner;

            return dialog;
        }
    }
}
using System;
using System.Windows.Input;

namespace MvvmDialog1.ViewModel.Utils
{
    class RelayCommand : ICommand
    {
        readonly Action<object> _method;
        readonly Predicate<object> _condition;

        public RelayCommand(Action<object> method) : this(method, null) { }

        public RelayCommand(Action<object> method, Predicate<object> condition)
        {
            this._condition = condition;
            this._method = method;
        }

        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        public bool CanExecute(object parameter)
        {
            return this._condition == null ? true : this._condition(parameter);
        }

        public void Execute(object parameter)
        {
            this._method(parameter);
        }

        public void Execute()
        {
            this._method(null);
        }
    }
}
using MvvmDialog1.ViewModel.Interfaces;
using MvvmDialog1.ViewModel.Utils;
using System;
using System.Windows;
using System.Windows.Input;

namespace MvvmDialog1.ViewModel.ViewModels
{
    class WindowViewModel : BaseViewModel, IDialogRequestClose
    {
        string _message;

        public string Message
        {
            get
            {
                return this._message;
            }
            set
            {
                this._message = value;                
                this.OnPropertyChanged("Message");
            }
        }

        /// <summary>
        /// Domyślny konstruktor wymagany przez Xaml.
        /// </summary>
        public WindowViewModel() { }

        /// <summary>
        /// Właściwy konstruktor stosowany przy tworzeniu instancji okna.
        /// </summary>
        /// <param name="message">Wiadomość wyświetlana w oknie. Zamiast tego mogą być jakiekolwiek inne zmienne.</param>
        public WindowViewModel(string message)
        {
            this.Message = message;
        }

        public event EventHandler<DialogCloseRequestedEventArgs> CloseRequested;
    }
}

以上是关于csharp 自定义对话窗口的主要内容,如果未能解决你的问题,请参考以下文章

创建自定义 fltk 对话框/模态窗口

自定义 MFC 窗口/对话框可以是类模板实例化吗?

如何测试使用 exec_() 调用的自定义对话框窗口?

自定义对话框(jDialog)

自定义jquery模型窗口[重复]

Lync 2010 API - 禁止 Toast 和对话窗口