using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Windows; using System.Windows.Interop; namespace Szmedi.RevitToolkit.Approval.Assists { public static class WinDialogAssists { private static Dictionary _windows = new Dictionary(); public static void ShowOrActivate(params object[] viewModelParams) where TWindow : Window, new() where TViewModel : class { var windowType = typeof(TWindow); if (!_windows.ContainsKey(windowType) || _windows[windowType] == null) { //CloseAllWindowsExcept(windowType); AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; _windows[windowType] = new TWindow(); _windows[windowType].Closed += WindowClosed; _windows[windowType].Closed += (sender, args) => _windows[windowType] = null; if (_windows[windowType].DataContext == null || !(_windows[windowType].DataContext is TViewModel)) { if (viewModelParams.Length == 0) { _windows[windowType].DataContext = Activator.CreateInstance(typeof(TViewModel)); } else { _windows[windowType].DataContext = Activator.CreateInstance(typeof(TViewModel), viewModelParams); } } _ = new WindowInteropHelper(_windows[windowType]) { Owner = Process.GetCurrentProcess().MainWindowHandle }; _windows[windowType].Show(); } else { _windows[windowType].Activate(); } } private static void WindowClosed(object sender, EventArgs e) { AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; } private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { StackFrame[] frames = new StackTrace().GetFrames(); if (frames == null) { return null; } string name = new AssemblyName(args.Name).Name; List list = new List(); for (int i = 0; i < frames.Length; i++) { MethodBase method = frames[i].GetMethod(); if ((object)method.DeclaringType == null) { continue; } string directoryName = Path.GetDirectoryName(method.DeclaringType.Assembly.Location); if (list.Contains(directoryName)) { continue; } list.Add(directoryName); foreach (string item in Directory.EnumerateFiles(directoryName, "*.dll")) { if (name == Path.GetFileNameWithoutExtension(item)) { return Assembly.LoadFile(item); } } } return null; } //private static T instance; //private static readonly object padlock = new(); //public static T GetInstance(out bool IsNewCreate) //{ // IsNewCreate = false; // //double-check locking // if (instance == null) // { // IsNewCreate = true; // lock (padlock) // { // instance ??= new T(); // instance.Closed += OnWindowClosed; // } // } // return instance; //} //private static void OnWindowClosed(object sender, EventArgs e) //{ // instance = null; //} public static class LazySingleton where T : class, new() { private static readonly Lazy instance = new(() => new T(), LazyThreadSafetyMode.ExecutionAndPublication); public static T Instance => instance.Value; } /// /// 对话框过滤器 /// /// 过滤器的名称 /// 仅扩展名,如xlsx,*代表所有文件 /// public static string CreateFilter(string title, params string[] extensions) { if (extensions[0] == "*") { return "所有文件(*)|*"; } var str = string.Empty; for (var i = 0; i < extensions.Length; i++) { var extension = extensions[i]; str += $"*.{extension}"; if (i < extensions.Length - 1) { str += ";"; } } return $"{title}({str})|{str}"; } /// /// 释放命令行管理程序分配的ITEMIDLIST结构 /// Frees an ITEMIDLIST structure allocated by the Shell. /// /// [DllImport("shell32.dll", ExactSpelling = true)] public static extern void ILFree(IntPtr pidlList); /// /// 返回与指定文件路径关联的ITEMIDLIST结构。 /// Returns the ITEMIDLIST structure associated with a specified file path. /// /// /// [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] public static extern IntPtr ILCreateFromPathW(string pszPath); /// /// 打开一个Windows资源管理器窗口,其中选择了特定文件夹中的指定项目。 /// Opens a Windows Explorer window with specified items in a particular folder selected. /// /// /// /// /// /// [DllImport("shell32.dll", ExactSpelling = true)] public static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags); /// /// 打开或在现有目录并选中相应文件 /// /// static public void OpenFolderAndSelectFile(string fileFullName) { if (string.IsNullOrEmpty(fileFullName)) throw new ArgumentNullException(nameof(fileFullName)); fileFullName = Path.GetFullPath(fileFullName); var pidlList = ILCreateFromPathW(fileFullName); if (pidlList == IntPtr.Zero) return; try { Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0)); } finally { ILFree(pidlList); } } /// /// 新建一个资源管理器窗口并选中 /// /// public static void ExploreFile(string filePath) { Process proc = new(); proc.StartInfo.FileName = "explorer"; //打开资源管理器 proc.StartInfo.Arguments = @"/select," + filePath; //选中"notepad.exe"这个程序,即记事本 proc.Start(); } /// /// 打开窗口,非模态窗口置顶显示,默认非模态 /// /// public static void ShowAhead(this Window window) { _ = new WindowInteropHelper(window) { Owner = Process.GetCurrentProcess().MainWindowHandle }; window.Show(); } } }