using System.Diagnostics; using System.IO; using System.Reflection; using System.Windows; using System.Windows.Interop; using Autodesk.Revit.DB; using CommunityToolkit.Mvvm.ComponentModel; using Microsoft.Win32; namespace ShrlAlgoToolkit.RevitAddins.Common.Assists; public static class WinDialogAssist { /// /// 对话框过滤器 /// /// 过滤器的名称 /// 仅扩展名,*代表所有文件 /// public static Microsoft.Win32.FileDialog SetFilter(this Microsoft.Win32.FileDialog dialog, string filterName, params string[] extensions) { if (extensions[0] == "*") { dialog.Filter = "所有文件(*)|*"; //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 += ";"; } } dialog.Filter = $"{filterName}({str})|{str}"; return dialog; //return $"{filterName}({str})|{str}"; } /// /// 打开或在现有目录并选中相应文件 /// /// public static void OpenFolderAndSelectFile(string fileFullName) { if (string.IsNullOrEmpty(fileFullName)) throw new ArgumentNullException(nameof(fileFullName)); if (!File.Exists(fileFullName)) { throw new FileNotFoundException("指定的文件不存在", fileFullName); } var proc = new Process(); proc.StartInfo.FileName = "explorer"; //打开资源管理器 proc.StartInfo.Arguments = "/select," + fileFullName; proc.Start(); } /// /// 新建一个资源管理器窗口并选中文件或文件夹 /// /// public static void ExploreFile(string fileOrFolderPath) { //Process proc = new(); //proc.StartInfo.FileName = "explorer"; ////打开资源管理器 //proc.StartInfo.Arguments = @"/select," + fileOrFolderPath; ////选中"notepad.exe"这个程序,即记事本 //proc.Start(); Process.Start("explorer.exe", $"/select,\"{fileOrFolderPath}\""); } /// /// 选择文件 /// /// /// /// public static string GetSelectedFilePath(string title, params string[] extensions) { OpenFileDialog dialog = new() { CheckFileExists = true, InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), }; dialog.SetFilter(title, extensions); return dialog.ShowDialog() == true ? dialog.FileName : null; } public static void UpdateViewDisplay(PreviewControl currentPreviewControl, System.Windows.Controls.Grid previewContainer, Document backgroundDoc, View view, ViewDetailLevel detailLevel, DisplayStyle displayStyle) { if (backgroundDoc == null || view == null) return; backgroundDoc.Invoke( _ => { try { view.DetailLevel = detailLevel; view.DisplayStyle = displayStyle; } catch (Exception ex) { MessageBox.Show(ex.Message); } }); // 2. 销毁旧控件 if (currentPreviewControl != null) { previewContainer.Children.Clear(); currentPreviewControl.Dispose(); currentPreviewControl = null; } // 3. 创建新控件并加入 UI currentPreviewControl = new PreviewControl(backgroundDoc, view.Id); previewContainer.Children.Add(currentPreviewControl); } /// /// 打开窗口,非模态窗口置顶显示,默认非模态 /// /// private static void ShowAhead(this Window window) { _ = new WindowInteropHelper(window) { Owner = Process.GetCurrentProcess().MainWindowHandle }; window.Show(); } public static void ShowModeless(ObservableObject viewModel) where T : Window, new() { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; var view = SingletonViewAssist.GetInstance(out var isNewCreate); if (isNewCreate) { view.DataContext = viewModel; view.ShowAhead(); } view.Activate(); AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; } private static readonly Dictionary Windows = []; public static void ShowOrActivate(params object[] viewModelParams) where TView : Window,new() where TViewModel : class { var windowType = typeof(TView); if (!Windows.ContainsKey(windowType) || Windows[windowType] == null) { //CloseAllWindowsExcept(windowType); AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; Windows[windowType] = new TView(); Windows[windowType].Closed += WindowClosed; Windows[windowType].Closed += (_, _) => Windows[windowType] = null; if (Windows[windowType].DataContext == null || !(Windows[windowType].DataContext is TViewModel)) { Windows[windowType].DataContext = viewModelParams.Length == 0 ? Activator.CreateInstance(typeof(TViewModel)) : 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; } public static void ShowDialog(params object[] viewModelParams) where TWindow : Window, new() where TViewModel : class { var window = new TWindow { DataContext = viewModelParams.Length == 0 ? Activator.CreateInstance(typeof(TViewModel)) : Activator.CreateInstance(typeof(TViewModel), viewModelParams) }; _ = new WindowInteropHelper(window) { Owner = Process.GetCurrentProcess().MainWindowHandle }; window.ShowDialog(); } 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(); foreach (var t in frames) { MethodBase method = t.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; } }