添加项目文件。
This commit is contained in:
479
Sai.RvKits/RvFamily/FamilyLibrary/FamilyLibraryViewModel.cs
Normal file
479
Sai.RvKits/RvFamily/FamilyLibrary/FamilyLibraryViewModel.cs
Normal file
@@ -0,0 +1,479 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using FuzzySharp;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
using Wpf.Ui.Extend.Controls;
|
||||
|
||||
using Settings = Sai.RvKits.Properties.Settings;
|
||||
|
||||
namespace Sai.RvKits.RvFamily.FamilyLibrary;
|
||||
|
||||
public partial class FamilyLibraryViewModel : ObservableObject
|
||||
{
|
||||
public FamilyLibraryViewModel()
|
||||
{
|
||||
loadFamilyHandler = new ActionEventHandler();
|
||||
loadFamilySymbolHandler = new ActionEventHandler();
|
||||
#if REVIT2018
|
||||
familyPath = Settings.Default.FamilyPath_2018;
|
||||
#elif REVIT2019
|
||||
familyPath = Settings.Default.FamilyPath_2019;
|
||||
#elif REVIT2020
|
||||
familyPath = Settings.Default.FamilyPath_2020;
|
||||
#elif REVIT2021
|
||||
familyPath = Settings.Default.FamilyPath_2021;
|
||||
#endif
|
||||
PageSize = 20;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private readonly ActionEventHandler loadFamilyHandler;
|
||||
private readonly ActionEventHandler loadFamilySymbolHandler;
|
||||
|
||||
[ObservableProperty]
|
||||
private string familyPath;
|
||||
|
||||
[ObservableProperty]
|
||||
private int pageCount;
|
||||
|
||||
[ObservableProperty]
|
||||
private int pageSize;
|
||||
|
||||
[ObservableProperty]
|
||||
private string revitVersion;
|
||||
|
||||
[ObservableProperty]
|
||||
private FamilyModel selectedFamily;
|
||||
|
||||
[ObservableProperty]
|
||||
private FamilySymbolType selectedSymbolType;
|
||||
|
||||
[ObservableProperty]
|
||||
private List<FamilySymbolType> symbolTypes;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool activeSnackbar;
|
||||
|
||||
[ObservableProperty]
|
||||
private Wpf.Ui.Controls.InfoBar messageQueue = new();
|
||||
|
||||
[ObservableProperty]
|
||||
private string message;
|
||||
|
||||
partial void OnMessageChanged(string value)
|
||||
{
|
||||
ActiveSnackbar = true;
|
||||
}
|
||||
|
||||
public int FamilyCount => FamilyDataSource.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 选择树路径时的源
|
||||
/// </summary>
|
||||
public ObservableCollection<FamilyModel> FamilyDataSource { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 单页显示的源
|
||||
/// </summary>
|
||||
public ObservableCollection<FamilyModel> FamilyPageListViewItems { get; set; } = new();
|
||||
|
||||
public ObservableCollection<TreeViewItem> FolderTreeViewItems { get; set; } = new();
|
||||
|
||||
[RelayCommand]
|
||||
private void LvScroll(ScrollViewer scrollViewer)
|
||||
{
|
||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||
if (!isLoadingData && scrollViewer.VerticalOffset + scrollViewer.ViewportHeight == scrollViewer.ExtentHeight)
|
||||
{
|
||||
LoadMoreData();
|
||||
}
|
||||
}
|
||||
|
||||
private const int BatchSize = 10;
|
||||
private bool isLoadingData;
|
||||
|
||||
/// <summary>
|
||||
/// 加载目录树节点的初始化数据
|
||||
/// </summary>
|
||||
private void LoadInitialData()
|
||||
{
|
||||
isLoadingData = true;
|
||||
FamilyPageListViewItems.Clear();
|
||||
var size = BatchSize;
|
||||
if (FamilyDataSource.Count < BatchSize)
|
||||
{
|
||||
size = FamilyDataSource.Count;
|
||||
}
|
||||
for (var i = 0; i < size; i++)
|
||||
{
|
||||
FamilyPageListViewItems.Add(FamilyDataSource[i]);
|
||||
}
|
||||
isLoadingData = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 懒加载
|
||||
/// </summary>
|
||||
private void LoadMoreData()
|
||||
{
|
||||
isLoadingData = true;
|
||||
var startIndex = FamilyPageListViewItems.Count;
|
||||
var end = startIndex + BatchSize;
|
||||
if (end > FamilyDataSource.Count)
|
||||
{
|
||||
end = FamilyDataSource.Count;
|
||||
}
|
||||
if (startIndex < end + 1)
|
||||
{
|
||||
for (var i = startIndex; i < end; i++)
|
||||
{
|
||||
FamilyPageListViewItems.Add(FamilyDataSource[i]);
|
||||
}
|
||||
}
|
||||
isLoadingData = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归获取路径下的所有族文件
|
||||
/// </summary>
|
||||
/// <param name="fullPath"></param>
|
||||
private void GetFamilyFile(string fullPath)
|
||||
{
|
||||
DirectoryInfo dir = new(fullPath);
|
||||
try
|
||||
{
|
||||
if (!dir.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//文件系统,包含文件夹和文件
|
||||
var files = dir.GetFileSystemInfos();
|
||||
foreach (var fSys in files)
|
||||
{
|
||||
//FSys如果是文件则fileinfo不为空
|
||||
|
||||
if (fSys is FileInfo fileInfo)
|
||||
{
|
||||
if (fileInfo.Extension == ".rfa")
|
||||
{
|
||||
var sfInfo = new FileInfo(fileInfo.DirectoryName + "\\" + fileInfo.Name);
|
||||
//RevitFileUtil.ParserRevitFile(sfInfo.FullName);
|
||||
var model = new FamilyModel
|
||||
{
|
||||
FileInfo = sfInfo,
|
||||
Path = sfInfo.FullName,
|
||||
Title = Path.GetFileNameWithoutExtension(sfInfo.FullName),
|
||||
ToolTip = sfInfo.Name
|
||||
//RevitVersion = RevitFileUtil.RevitVersion
|
||||
};
|
||||
|
||||
FamilyDataSource.Add(model);
|
||||
}
|
||||
}
|
||||
else //当fileinfo为空,即为文件夹,向下查找
|
||||
{
|
||||
GetFamilyFile($"{fullPath}\\{fSys}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将族加载到当前文件中
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void ImportFamily(FamilyModel model)
|
||||
{
|
||||
//将model的绑定数据传给外部事件
|
||||
loadFamilyHandler.Raise(app =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var doc = app.ActiveUIDocument.Document;
|
||||
Family family;
|
||||
FamilySymbol fs = null;
|
||||
doc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
family = doc.GetOrLoadedFamily(model.Path);
|
||||
fs = doc.GetElement(family.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol;
|
||||
//if (fs != null && !fs.IsActive)
|
||||
//{
|
||||
// fs.Activate();
|
||||
//}
|
||||
//if (family == null)
|
||||
//{
|
||||
// doc.LoadFamily(FileLibModel.Path, familyLoadOption, out family);
|
||||
// fs = doc.GetElement(family.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol;
|
||||
//
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// MessageBox.ShowAhead("族已载入或载入失败。", "提示");
|
||||
//}
|
||||
},
|
||||
"载入族-" + Path.GetFileNameWithoutExtension(model.Path)
|
||||
);
|
||||
if (fs != null && app.ActiveUIDocument.CanPlaceElementType(fs))
|
||||
{
|
||||
app.ActiveUIDocument.PromptForFamilyInstancePlacement(fs);
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
|
||||
catch (Exception e)
|
||||
{
|
||||
Message = e.Message;
|
||||
e.Message.ToLog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void ImportFamilySymbol()
|
||||
{
|
||||
if (SelectedFamily == null || SelectedSymbolType == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loadFamilySymbolHandler.Raise(app =>
|
||||
{
|
||||
var uidoc = app.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
//当前选择的族类型
|
||||
FamilySymbol fs = null;
|
||||
if (SelectedSymbolType.Name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
doc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
var fam = doc.GetOrLoadedFamily(SelectedFamily.Path);
|
||||
doc.Regenerate();
|
||||
//if (fam == null)
|
||||
//{
|
||||
// doc.LoadFamilySymbol(FamilyPath, FamilySymbolName, out fs);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
var x = fam.GetFamilySymbolIds()
|
||||
.FirstOrDefault(id => doc.GetElement(id).Name == SelectedSymbolType.Name);
|
||||
fs = doc.GetElement(x) as FamilySymbol;
|
||||
//}
|
||||
if (fs?.IsActive == false)
|
||||
{
|
||||
fs.Activate();
|
||||
}
|
||||
},
|
||||
"载入族-" + Path.GetFileNameWithoutExtension(SelectedFamily.Path) + " 类型:" + SelectedSymbolType.Name
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
if (fs != null && uidoc.CanPlaceElementType(fs))
|
||||
{
|
||||
app.ActiveUIDocument.PromptForFamilyInstancePlacement(fs);
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
|
||||
catch (Exception e)
|
||||
{
|
||||
e.Message.ToLog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
PopulateTreeView(FamilyPath);
|
||||
GetFamilyFile(FamilyPath);
|
||||
//CurrentPageIndex = 0;
|
||||
LoadInitialData();
|
||||
//PageCount = GetPageCount();
|
||||
//PageOrderNumberCollection = GetOrderIntCollection();
|
||||
//CollectionViewSource.GetDefaultView(FamilyPageListViewItems);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private static void LocationFamilyFile(object obj)
|
||||
{
|
||||
//System.Windows.Controls.Button btn = obj as System.Windows.Controls.Button;
|
||||
if (obj is FamilyModel familyInfo)
|
||||
{
|
||||
var proc = new System.Diagnostics.Process();
|
||||
proc.StartInfo.FileName = "explorer";
|
||||
//打开资源管理器
|
||||
proc.StartInfo.Arguments = "/select," + familyInfo.Path;
|
||||
proc.Start();
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void LvSelectionChanged(object obj)
|
||||
{
|
||||
if (obj is FamilyModel familyInfo)
|
||||
{
|
||||
RevitFileUtil.ParserRevitFile(familyInfo.Path);
|
||||
SymbolTypes = RevitFileUtil.SymbolTypes;
|
||||
SelectedSymbolType = SymbolTypes.FirstOrDefault();
|
||||
RevitVersion = RevitFileUtil.RevitVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定TreeView数据源.
|
||||
/// </summary>
|
||||
/// <param name="path">The Path<see cref="string" />.</param>
|
||||
private void PopulateTreeView(string path)
|
||||
{
|
||||
FolderTreeViewItems?.Clear();
|
||||
|
||||
var info = new DirectoryInfo(path);
|
||||
if (!info.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rootNode = new TreeViewItem { Header = info.Name, Tag = info.FullName };
|
||||
|
||||
/* 项目“Sai.RvKits (net481)”的未合并的更改
|
||||
在此之前:
|
||||
SubDirectories(info.GetDirectories(), rootNode);
|
||||
在此之后:
|
||||
FamilyLibraryViewModel.SubDirectories(info.GetDirectories(), rootNode);
|
||||
*/
|
||||
SubDirectories(info.GetDirectories(), rootNode);
|
||||
//dirTree.DataContext = rootNode;
|
||||
FolderTreeViewItems!.Add(rootNode);
|
||||
rootNode.IsExpanded = true;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SearchFamily(object obj)
|
||||
{
|
||||
//ListViewItem foundItem =
|
||||
// textListView.FindItemWithText(searchBox.Text, false, 0, true);
|
||||
//if (foundItem != null)
|
||||
//{
|
||||
// textListView.TopItem = foundItem;
|
||||
//}
|
||||
//Func<string, bool> searchFunc = BreakCurve;
|
||||
//Task<bool> task = new Task<bool>(() => BreakCurve(obj.ToString()));
|
||||
//task.Start();
|
||||
//await task;
|
||||
if (string.IsNullOrEmpty(obj.ToString()))
|
||||
{
|
||||
LoadInitialData();
|
||||
//FamilyPageListViewItems.Clear();
|
||||
//itemsLoaded.ForEach(item => FamilyPageListViewItems.Add(item));
|
||||
}
|
||||
else
|
||||
{
|
||||
//itemsLoaded.Clear();
|
||||
//FamilyPageListViewItems.ForEach(item => itemsLoaded.Add(item));
|
||||
FamilyPageListViewItems.Clear();
|
||||
foreach (var item in FamilyDataSource)
|
||||
{
|
||||
if (Fuzz.PartialRatio(item.Title,obj.ToString())>70)
|
||||
{
|
||||
FamilyPageListViewItems.Add(item);
|
||||
|
||||
}
|
||||
//if (item.Title.Contains(obj.ToString()))
|
||||
//{
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选择树状节点
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
[RelayCommand]
|
||||
private void SelectDirTreeNode(object obj)
|
||||
{
|
||||
//e.OriginalSource 就是TreeViewItem对象,你可以将其保存到窗体类的某个私有字段中,或者直接使用它,如下所示:
|
||||
FamilyDataSource.Clear();
|
||||
if (obj is TreeViewItem selectedItem)
|
||||
{
|
||||
GetFamilyFile(selectedItem.Tag.ToString());
|
||||
}
|
||||
LoadInitialData();
|
||||
SymbolTypes = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路径选择.
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void SelectPath()
|
||||
{
|
||||
var dialog = new VistaFolderBrowserDialog();
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
#if REVIT2018
|
||||
Settings.Default.FamilyPath_2018 = dialog.SelectedPath;
|
||||
#elif REVIT2019
|
||||
Settings.Default.FamilyPath_2019 = dialog.SelectedPath;
|
||||
#elif REVIT2020
|
||||
Settings.Default.FamilyPath_2020 = dialog.SelectedPath;
|
||||
#elif REVIT2021
|
||||
Settings.Default.FamilyPath_2021 = dialog.SelectedPath;
|
||||
#endif
|
||||
PopulateTreeView(dialog.SelectedPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归添加目录结构到TreeView根节点.
|
||||
/// </summary>
|
||||
/// <param name="subDirs">.</param>
|
||||
/// <param name="nodeToAddTo">根节点.</param>
|
||||
private static void SubDirectories(DirectoryInfo[] subDirs, TreeViewItem nodeToAddTo)
|
||||
{
|
||||
//父节点
|
||||
foreach (var subDir in subDirs)
|
||||
{
|
||||
var aNode = new TreeViewItem { Header = subDir.Name, Tag = subDir.FullName };
|
||||
//获取子目录
|
||||
var subSubDirs = subDir.GetDirectories();
|
||||
if (subSubDirs.Length != 0)
|
||||
{
|
||||
/* 项目“Sai.RvKits (net481)”的未合并的更改
|
||||
在此之前:
|
||||
SubDirectories(subSubDirs, aNode);
|
||||
在此之后:
|
||||
FamilyLibraryViewModel.SubDirectories(subSubDirs, aNode);
|
||||
*/
|
||||
SubDirectories(subSubDirs, aNode);
|
||||
}
|
||||
|
||||
nodeToAddTo.Items.Add(aNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user