using System.Collections; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using Autodesk.Revit.DB; using Autodesk.Revit.UI; namespace Szmedi.RvKits.ModelManager; public partial class RenameFamilyViewModel : ObservableObject { public RenameFamilyViewModel(UIApplication uiApplication) { doc = uiApplication.ActiveUIDocument.Document; allCategories = GetCategoriesFromDocument(); Collection = allCategories; //ICollectionView cv = CollectionViewSource.GetDefaultView(Categories); //cv.Filter = item => string.IsNullOrEmpty(SearchText) || // ((KeyValuePair)item).Value.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0; //TaskDialog.Show("数量", CategoriesDictionary.Count.ToString()); } //[ObservableProperty] //private List selectedBuiltInCategories; private readonly Dictionary> allCategories; //public ICollectionView CategoriesCollectionView { get; set; } private readonly Document doc; [ObservableProperty] private bool canInput; [ObservableProperty] private bool isRunning; [ObservableProperty] public partial Dictionary> Collection { get; set; } [ObservableProperty] private int categoryCount; [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(ModifyNameCommand))] private List renameItems; [ObservableProperty] private bool isUsed; [ObservableProperty] private string foundText; [ObservableProperty] private string prefixText; [ObservableProperty] private string replaceText; [ObservableProperty] private string searchText; [ObservableProperty] private string separator = "-"; [ObservableProperty] private string suffixText; // ReSharper disable once ConditionIsAlwaysTrueOrFalse public bool CanModify => RenameItems?.Any(item => item.IsSelected) == true; [RelayCommand] private void PreviewTextInput(TextCompositionEventArgs args) { if (args != null && args.Source is System.Windows.Controls.ComboBox cb) { if (cb.Text == cb.SelectedItem?.ToString()) { args.Handled = true; } } } public bool? IsAllItemsSelected { get { var selected = RenameItems?.Select(item => item.IsSelected).Distinct().ToList(); if (selected == null) { return false; } return selected.Count == 1 ? selected.Single() : null; } set { if (value.HasValue) { SelectAll(value.Value, RenameItems); OnPropertyChanged(); } } } partial void OnIsUsedChanged(bool value) { if (value) { var collector = doc.OfCollector().WhereElementIsNotElementType(); foreach (var item in RenameItems) { foreach (var id in item.Family.GetFamilySymbolIds()) { var b = collector.Any(e => e.GetTypeId() == id); if (b) { item.IsSelected = true; break; } } } } } public Dictionary> GetCategoriesFromDocument() { var dict = doc.OfClass() .Cast() .Where(f => f.FamilyCategory is { CategoryType: CategoryType.Model or CategoryType.Annotation }) .GroupBy(f => f.FamilyCategory.Id) .Where(g => !string.IsNullOrEmpty(g.FirstOrDefault().FamilyCategory?.Name)) .ToDictionary(g => g.FirstOrDefault().FamilyCategory?.Name, g => g.ToList()); CategoryCount = dict.Count; return dict; //foreach (BuiltInCategory builtInCategory in Enum.GetValues(typeof(BuiltInCategory))) //{ // Category category = Category.GetCategory(doc, builtInCategory); // if (category is // { // CategoryType: CategoryType.Model or CategoryType.Annotation, // AllowsBoundParameters: true // }) // { // var familyType = new FilteredElementCollector(doc) // .QueryElementsByType(typeof(Family)) // .OfCategory(builtInCategory) // .Cast() // .ToList(); // if (familyType.Any()) // { // var name = category.Name; // items.Add(builtInCategory, name); // } // } //} //CategoryCount = items.Count; //return items.OrderBy(kv => kv.Value).ToDictionary(kv => kv.Key, kv => kv.Value); } [RelayCommand(CanExecute = nameof(CanModify))] private async Task ModifyName() { await Task.Delay(2_00); ModifyFamilyName(); } /// /// 获取列表中所有条目的新名称 /// private void GetNewNames() { var selectedItems = RenameItems.Where(item => item.IsSelected); foreach (var renameItem in selectedItems) { var tempName = renameItem.OldFamilyName; if (!string.IsNullOrEmpty(FoundText)) { tempName = tempName.Replace(FoundText, string.IsNullOrEmpty(ReplaceText) ? string.Empty : ReplaceText); } if (!string.IsNullOrEmpty(PrefixText)) { tempName = tempName.Insert(0, $"{PrefixText}{Separator}"); } if (!string.IsNullOrEmpty(SuffixText)) { tempName += $"{Separator}{SuffixText}"; } renameItem.NewFamilyName = tempName; } } /// /// 获取重命名的条目 /// /// [RelayCommand] private void GetRenameItems(IList items) { if (items.Count == 0) { RenameItems = null!; CanInput = false; return; } List familyItems = []; foreach (var item in items) { if (item is KeyValuePair> categoryItems) { //var familyType = new FilteredElementCollector(doc) // .QueryElementsByType(typeof(Family)) // .Cast() // .Where( // f => f.FamilyCategory.Id.IntegerValue == new ElementId(categoryItem.Key).IntegerValue // ); foreach (var family in categoryItems.Value) { RenameFamilyItem renameItem = new() { OldFamilyName = family.Name, Family = family, CategoryName = categoryItems.Key }; familyItems.Add(renameItem); } } } CanInput = familyItems.Any(); RenameItems = familyItems; //IsAllItemsSelected = true; foreach (var renameItem in RenameItems) { renameItem.PropertyChanged += (sender, args) => { //选中属性修改时,触发 if (args.PropertyName == nameof(RenameFamilyItem.IsSelected)) { OnPropertyChanged(nameof(IsAllItemsSelected)); ModifyNameCommand.NotifyCanExecuteChanged(); if (string.IsNullOrEmpty(renameItem.NewFamilyName)) { GetNewNames(); } } //单个修改名称时 //if (args.PropertyName == nameof(RenameFamilyItem.NewFamilyName)) //{ // ModifyFamilyName(); //} }; } } /// /// 修改族名称 /// private void ModifyFamilyName() { var needToRename = RenameItems.Where(item => item.IsSelected); doc.Invoke( ts => { var sb = new StringBuilder(); foreach (var renameItem in needToRename) { try { if (!string.IsNullOrEmpty(renameItem.NewFamilyName) && renameItem.NewFamilyName != renameItem.OldFamilyName) { renameItem.Family.Name = renameItem.NewFamilyName; renameItem.OldFamilyName = renameItem.NewFamilyName; } } catch (Exception ex) { sb.AppendLine($"{renameItem.OldFamilyName}-{ex.Message}"); continue; } } if (sb.Length > 0) { MessageBox.Show(sb.ToString(), "修改失败"); } }, "修改族名称"); } partial void OnFoundTextChanged(string value) { GetNewNames(); } partial void OnPrefixTextChanged(string value) { GetNewNames(); } partial void OnReplaceTextChanged(string value) { GetNewNames(); } partial void OnSearchTextChanged(string value) { Collection = allCategories .Where(kv => string.IsNullOrEmpty(value) || kv.Key.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) .ToDictionary(k => k.Key, v => v.Value); CategoryCount = Collection.Count; //CategoriesCollectionView.Refresh(); } partial void OnSeparatorChanged(string value) { GetNewNames(); } partial void OnSuffixTextChanged(string value) { GetNewNames(); } private static void SelectAll(bool select, IEnumerable models) { foreach (var model in models) { model.IsSelected = select; } } }