qin
2024-08-29 7d3aa07f6f94c70ca0a631a45db6565a5a58d9cf
HStation.RevitDev/RevitDataExport/Forms/Wpf_FamilyPanel.xaml.cs
@@ -1,311 +1,309 @@
using Autodesk.Revit.UI;
using HStation.RevitDev.Model.Enum;
using HStation.RevitDev.RevitDataExport.Common;
using HStation.RevitDev.RevitDataExport.Entity;
using HStation.RevitDev.RevitDataExport.Utility;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Button = System.Windows.Controls.Button;
namespace HStation.RevitDev.RevitDataExport.Forms
{
    /// <summary>
    /// WPF_FamilyPanel.xaml 的交互逻辑
    /// </summary>
    public partial class Wpf_FamilyPanel : UserControl, IDockablePaneProvider
    {
        //外部事件
        ExternalEvent_CreateInstance m_createInstanceEvent = null;
        ExternalEvent_CreatePipe m_createPipeEvent = null;
        ExternalEvent m_createInstanceHandler = null;
        ExternalEvent m_createPipeHandler = null;
        private string m_familyFileDir;
        private RevitFamilyType m_type;
        //面板上的按钮缓存
        private List<Button> m_displayFamilys = new List<Button>();
        private List<Button> m_realFamilys = new List<Button>();
        public Wpf_FamilyPanel(RevitFamilyType type)
        {
            m_type = type;
            m_familyFileDir = Path.Combine(GlobalResource.FamilysDirectory, type.GetDescription());
            InitializeComponent();
            if (type == RevitFamilyType.RFT_Pipe)
            {
                InitializePipeButton();
            }
            else
            {
                InitializeCostomControls();
            }
            m_createInstanceEvent = new ExternalEvent_CreateInstance();
            m_createPipeEvent = new ExternalEvent_CreatePipe();
            m_createInstanceHandler = ExternalEvent.Create(m_createInstanceEvent);
            m_createPipeHandler = ExternalEvent.Create(m_createPipeEvent);
        }
        private void InitializePipeButton()
        {
            var pipeDir = Path.Combine(GlobalResource.FamilysDirectory, RevitFamilyType.RFT_Pipe.GetDescription());
            var filePaths = Directory.GetFiles(pipeDir);
            foreach (var filePath in filePaths)
            {
                Button btn = CreatePipeButton(filePath);
                m_realFamilys.Add(btn);
                m_displayFamilys.Add(btn);
                wrapPanel_family2.Children.Add(btn);
            }
        }
        private Button CreatePipeButton(string filePath)
        {
            var fileName = Path.GetFileName(filePath);
            Button btn = new Button();
            btn.Height = GlobalResource.ThumbnailSize;
            btn.Width = GlobalResource.ThumbnailSize;
            btn.Content = fileName;
            btn.VerticalContentAlignment = VerticalAlignment.Bottom;
            btn.ToolTip = fileName;
            var bitmapPath = Path.Combine(GlobalResource.FamilysDirectory, RevitFamilyType.RFT_Pipe.GetDescription(), "默认.png");
            var bitmap = new Bitmap(bitmapPath);
            ImageBrush imageBrush = new ImageBrush();
            imageBrush.ImageSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            btn.Background = imageBrush;
            btn.Click += PipeBtnClick;
            return btn;
        }
        private void PipeBtnClick(object sender, RoutedEventArgs e)
        {
            GlobalResource.PipePlacing = true;
            GlobalResource.RevitFamilyType = m_type;
            m_createPipeHandler.Raise();
        }
        private void InitializeCostomControls()
        {
            string[] filePaths = Directory.GetFiles(m_familyFileDir, "*.rfa", SearchOption.TopDirectoryOnly);
            foreach (string rfaPath in filePaths)
            {
                AddToFamilyPanel(rfaPath);
            }
        }
        private void AddToFamilyPanel(string rfaPath)
        {
            Bitmap bitmap = null;
            var dir = Path.GetDirectoryName(rfaPath);
            var pngName = Path.GetFileNameWithoutExtension(rfaPath);
            var pngPath = Path.Combine(dir, pngName + ".png");
            if (!File.Exists(pngPath))
            {
                bitmap = ThumbnailUtils.GetThumbnailWithoutRevit(rfaPath);
            }
            else
            {
                bitmap = Bitmap.FromFile(pngPath) as Bitmap;
            }
            ContextMenu menu = CreateInstanceDeleteMenu();
            Button btn = CreateInstanceButton(rfaPath, bitmap);
            btn.ContextMenu = menu;
            menu.Tag = btn;
            m_realFamilys.Add(btn);
            m_displayFamilys.Add(btn);
            this.wrapPanel_family2.Children.Add(btn);
        }
        private Button CreateInstanceButton(string rfaPath, Bitmap bitmap)
        {
            Button btn = new Button();
            btn.Height = GlobalResource.ThumbnailSize;
            btn.Width = GlobalResource.ThumbnailSize;
            btn.Tag = rfaPath;
            btn.Content = Path.GetFileName(rfaPath);
            btn.VerticalContentAlignment = VerticalAlignment.Bottom;
            btn.ToolTip = btn.Content;
            ImageBrush imageBrush = new ImageBrush();
            imageBrush.ImageSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            btn.Background = imageBrush;
            btn.Click += FamilyBtnClick;
            return btn;
        }
        private ContextMenu CreateInstanceDeleteMenu()
        {
            ContextMenu menu = new ContextMenu();
            menu.StaysOpen = true;
            var item = new MenuItem();
            item.Click += (s, e) =>
            {
                var result = TaskDialog.Show("提示", "是否确定删除?", TaskDialogCommonButtons.Yes| TaskDialogCommonButtons.No);
                if (result == TaskDialogResult.Yes)
                {
                    MenuItem mItem = s as MenuItem;
                    ContextMenu cMenu = mItem.Parent as ContextMenu;
                    DeleteCurrentButton((Button)(cMenu.Tag));
                }
            };
            item.Header = "删除";
            item.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(200, 0, 0));
            menu.Items.Add(item);
            return menu;
        }
        private void DeleteCurrentButton(Button btn)
        {
            File.Delete(btn.Tag.ToString());
            m_displayFamilys.Remove(btn);
            m_realFamilys.Remove(btn);
            this.wrapPanel_family2.Children.Remove(btn);
        }
        private void FamilyBtnClick(object sender, RoutedEventArgs e)
        {
            GlobalResource.InstancePlacing = true;
            GlobalResource.RevitFamilyType = m_type;
            Button btn = sender as Button;
            m_createInstanceEvent.RfaPath = btn.Tag.ToString();
            m_createInstanceHandler.Raise();
        }
        public void SetupDockablePane(DockablePaneProviderData data)
        {
            data.FrameworkElement = this;
            DockablePaneState state = new DockablePaneState();
            state.DockPosition = DockPosition.Right;
            state.MinimumWidth = GlobalResource.ThumbnailSize;
            state.MinimumHeight = GlobalResource.ThumbnailSize;
            data.InitialState = state;
        }
        private void SearchBtnClick(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(searchBox.Text))
            {
                ShowAllFamilys();
                return;
            }
            m_displayFamilys.Clear();
            foreach (var child in this.m_realFamilys)
            {
                if (child is Button familyBtn)
                {
                    string filePath = familyBtn.Tag.ToString();
                    string fileName = Path.GetFileName(filePath);
                    if (fileName.ToUpper().Contains(searchBox.Text.ToUpper()))
                    {
                        m_displayFamilys.Add(familyBtn);
                    }
                }
            }
            wrapPanel_family2.Children.Clear();
            for (int i = 0; i < m_displayFamilys.Count; i++)
            {
                wrapPanel_family2.Children.Add(m_displayFamilys[i]);
            }
        }
        private void ShowAllFamilys()
        {
            wrapPanel_family2.Children.Clear();
            for (int i = 0; i < m_realFamilys.Count; i++)
            {
                wrapPanel_family2.Children.Add(m_realFamilys[i]);
            }
        }
        private void searchBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                SearchBtnClick(null, null);
            }
        }
        private void FamilyAddBtnClick(object sender, RoutedEventArgs e)
        {
            try
            {
                System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
                openFileDialog.FileName = "选择族文件";
                openFileDialog.Filter = "族文件(*.rfa)|*.rfa";
                openFileDialog.Title = "选择族文件";
                openFileDialog.Multiselect = true;
                if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
                var selectPaths = openFileDialog.FileNames;
                var validPaths = ValidateFileVersion(selectPaths);
                foreach (string path in validPaths)
                {
                    CopyToInstanceDirectory(path);
                    AddToFamilyPanel(path);
                }
            }
            catch (Exception ex)
            {
                TaskDialog.Show("错误", $"{ex.Message}");
            }
            TaskDialog.Show("提示", "添加成功!");
        }
        private void CopyToInstanceDirectory(string path)
        {
            var fileName = Path.GetFileName(path);
            var newPath = Path.Combine(GlobalResource.FamilysDirectory + $@"/{m_type.GetDescription()}", fileName);
            try
            {
                File.Copy(path, newPath, true);
            }
            catch (Exception ex)
            {
                TaskDialog.Show(path, $"文件复制失败,{ex.Message}");
            }
        }
        private IEnumerable<string> ValidateFileVersion(string[] selectPaths)
        {
            var result = new List<string>();
            foreach ( var selectPath in selectPaths)
            {
                var fileVersion = VersionUtil.GetVersion(selectPath);
                if (fileVersion == null)
                {
                    TaskDialog.Show("警告", "无法检测文件版本,载入族文件失败!");
                }
                if ( fileVersion.CompareTo(GlobalResource.CurrentRevitVersion) > 0)
                {
                    TaskDialog.Show("警告","文件版本高于当前Revit版本,无法载入族文件!");
                }
                else
                {
                    result.Add(selectPath);
                }
            }
            return result;
        }
    }
}
using Autodesk.Revit.UI;
using HStation.RevitDev.Model.ModelEnum;
using HStation.RevitDev.RevitDataExport.Common;
using HStation.RevitDev.RevitDataExport.Entity;
using HStation.RevitDev.RevitDataExport.Utility;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Button = System.Windows.Controls.Button;
namespace HStation.RevitDev.RevitDataExport.Forms
{
    /// <summary>
    /// WPF_FamilyPanel.xaml 的交互逻辑
    /// </summary>
    public partial class Wpf_FamilyPanel : UserControl, IDockablePaneProvider
    {
        //外部事件
        ExternalEvent_CreateInstance m_createInstanceEvent = null;
        ExternalEvent_CreatePipe m_createPipeEvent = null;
        ExternalEvent m_createInstanceHandler = null;
        ExternalEvent m_createPipeHandler = null;
        private string m_familyFileDir;
        private RevitType m_type;
        //面板上的按钮缓存
        private List<Button> m_displayFamilys = new List<Button>();
        private List<Button> m_realFamilys = new List<Button>();
        public Wpf_FamilyPanel(RevitType type)
        {
            m_type = type;
            m_familyFileDir = Path.Combine(GlobalResource.FamilysDirectory, type.GetDescription());
            InitializeComponent();
            if (type == RevitType.RFT_Pipe)
            {
                InitializePipeButton();
            }
            else
            {
                InitializeCostomControls();
            }
            m_createInstanceEvent = new ExternalEvent_CreateInstance();
            m_createPipeEvent = new ExternalEvent_CreatePipe();
            m_createInstanceHandler = ExternalEvent.Create(m_createInstanceEvent);
            m_createPipeHandler = ExternalEvent.Create(m_createPipeEvent);
        }
        private void InitializePipeButton()
        {
            var pipeDir = Path.Combine(GlobalResource.FamilysDirectory, RevitType.RFT_Pipe.GetDescription());
            var filePaths = Directory.GetFiles(pipeDir);
            foreach (var filePath in filePaths)
            {
                Button btn = CreatePipeButton(filePath);
                m_realFamilys.Add(btn);
                m_displayFamilys.Add(btn);
                wrapPanel_family2.Children.Add(btn);
            }
        }
        private Button CreatePipeButton(string filePath)
        {
            var fileName = Path.GetFileName(filePath);
            Button btn = new Button();
            btn.Height = GlobalResource.ThumbnailSize;
            btn.Width = GlobalResource.ThumbnailSize;
            btn.Content = fileName;
            btn.VerticalContentAlignment = VerticalAlignment.Bottom;
            btn.ToolTip = fileName;
            var bitmapPath = Path.Combine(GlobalResource.FamilysDirectory, RevitType.RFT_Pipe.GetDescription(), "默认.png");
            var bitmap = new Bitmap(bitmapPath);
            ImageBrush imageBrush = new ImageBrush();
            imageBrush.ImageSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            btn.Background = imageBrush;
            btn.Click += PipeBtnClick;
            return btn;
        }
        private void PipeBtnClick(object sender, RoutedEventArgs e)
        {
            GlobalResource.PlacingType = m_type;
            m_createPipeHandler.Raise();
        }
        private void InitializeCostomControls()
        {
            string[] filePaths = Directory.GetFiles(m_familyFileDir, "*.rfa", SearchOption.TopDirectoryOnly);
            foreach (string rfaPath in filePaths)
            {
                if (RevitUtil.IsBackUpFile(rfaPath))
                {
                    continue;
                }
                AddToFamilyPanel(rfaPath);
            }
        }
        private void AddToFamilyPanel(string rfaPath)
        {
            Bitmap bitmap = null;
            var dir = Path.GetDirectoryName(rfaPath);
            var pngName = Path.GetFileNameWithoutExtension(rfaPath);
            var pngPath = Path.Combine(dir, pngName + ".png");
            if (!File.Exists(pngPath))
            {
                bitmap = ThumbnailUtils.GetThumbnailWithoutRevit(rfaPath);
            }
            else
            {
                bitmap = Bitmap.FromFile(pngPath) as Bitmap;
            }
            ContextMenu menu = CreateInstanceDeleteMenu();
            Button btn = CreateInstanceButton(rfaPath, bitmap);
            btn.ContextMenu = menu;
            menu.Tag = btn;
            m_realFamilys.Add(btn);
            m_displayFamilys.Add(btn);
            this.wrapPanel_family2.Children.Add(btn);
        }
        private Button CreateInstanceButton(string rfaPath, Bitmap bitmap)
        {
            Button btn = new Button();
            btn.Height = GlobalResource.ThumbnailSize;
            btn.Width = GlobalResource.ThumbnailSize;
            btn.Tag = rfaPath;
            btn.Content = Path.GetFileName(rfaPath);
            btn.VerticalContentAlignment = VerticalAlignment.Bottom;
            btn.ToolTip = btn.Content;
            ImageBrush imageBrush = new ImageBrush();
            imageBrush.ImageSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            btn.Background = imageBrush;
            btn.Click += FamilyBtnClick;
            return btn;
        }
        private ContextMenu CreateInstanceDeleteMenu()
        {
            ContextMenu menu = new ContextMenu();
            try
            {
                menu.StaysOpen = true;
                var item = new MenuItem();
                item.Click += (s, e) =>
                {
                    var result = TaskDialog.Show("提示", "是否确定删除?", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No);
                    if (result == TaskDialogResult.Yes)
                    {
                        MenuItem mItem = s as MenuItem;
                        ContextMenu cMenu = mItem.Parent as ContextMenu;
                        DeleteButton((Button)(cMenu.Tag));
                    }
                };
                item.Header = "删除";
                item.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(200, 0, 0));
                menu.Items.Add(item);
            }
            catch (Exception ex)
            {
                TaskDialog.Show("错误", $"{ex.Message}");
            }
            return menu;
        }
        private void DeleteButton(Button btn)
        {
            try
            {
                File.Delete(btn.Tag.ToString());
            }
            catch (UnauthorizedAccessException ex)
            {
                TaskDialog.Show("错误", ex.Message + ":请检查文件属性是否可写!");
                return;
            }
            m_displayFamilys.Remove(btn);
            m_realFamilys.Remove(btn);
            this.wrapPanel_family2.Children.Remove(btn);
        }
        private void FamilyBtnClick(object sender, RoutedEventArgs e)
        {
            GlobalResource.PlacingType = m_type;
            Button btn = sender as Button;
            m_createInstanceEvent.RfaPath = btn.Tag.ToString();
            m_createInstanceHandler.Raise();
        }
        public void SetupDockablePane(DockablePaneProviderData data)
        {
            data.FrameworkElement = this;
            DockablePaneState state = new DockablePaneState();
            state.DockPosition = DockPosition.Right;
            state.MinimumWidth = GlobalResource.ThumbnailSize;
            state.MinimumHeight = GlobalResource.ThumbnailSize;
            data.InitialState = state;
        }
        private void SearchBtnClick(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(searchBox.Text))
            {
                ShowAllFamilys();
                return;
            }
            m_displayFamilys.Clear();
            foreach (var child in this.m_realFamilys)
            {
                if (child is Button familyBtn)
                {
                    string filePath = familyBtn.Tag.ToString();
                    string fileName = Path.GetFileName(filePath);
                    if (fileName.ToUpper().Contains(searchBox.Text.ToUpper()))
                    {
                        m_displayFamilys.Add(familyBtn);
                    }
                }
            }
            wrapPanel_family2.Children.Clear();
            for (int i = 0; i < m_displayFamilys.Count; i++)
            {
                wrapPanel_family2.Children.Add(m_displayFamilys[i]);
            }
        }
        private void ShowAllFamilys()
        {
            wrapPanel_family2.Children.Clear();
            for (int i = 0; i < m_realFamilys.Count; i++)
            {
                wrapPanel_family2.Children.Add(m_realFamilys[i]);
            }
        }
        private void searchBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                SearchBtnClick(null, null);
            }
        }
        private void FamilyAddBtnClick(object sender, RoutedEventArgs e)
        {
            try
            {
                System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
                openFileDialog.FileName = "选择族文件";
                openFileDialog.Filter = "族文件(*.rfa)|*.rfa";
                openFileDialog.Title = "选择族文件";
                openFileDialog.Multiselect = true;
                if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
                var selectPaths = openFileDialog.FileNames;
                var validPaths = RevitUtil.ValidateFileVersion(selectPaths).ToList();
                for (int i = 0; i < validPaths.Count(); i++)
                {
                    string path = validPaths[i];
                    CopyToInstanceDirectory(ref path);
                    AddToFamilyPanel(path);
                }
            }
            catch (Exception ex)
            {
                TaskDialog.Show("错误", $"{ex.Message}");
            }
            TaskDialog.Show("提示", "添加成功!");
        }
        private void CopyToInstanceDirectory(ref string path)
        {
            var fileName = Path.GetFileName(path);
            var newPath = Path.Combine(GlobalResource.FamilysDirectory + $@"/{m_type.GetDescription()}", fileName);
            try
            {
                File.Copy(path, newPath, true);
                path = newPath;
            }
            catch (Exception ex)
            {
                TaskDialog.Show(path, $"文件复制失败,{ex.Message}");
            }
        }
    }
}