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 RenameTypeViewModel : ObservableObject { public RenameTypeViewModel(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()); } [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; } } } //[ObservableProperty] //private List selectedBuiltInCategories; /// /// 所有类别及类型 /// private readonly Dictionary> allCategories; //public ICollectionView CategoriesCollectionView { get; set; } private readonly Document doc; /// /// 列表中元素 /// [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(ModifyNameCommand))] //[NotifyPropertyChangedFor(nameof(IsAllItemsSelected))] private List renameItems; [ObservableProperty] private bool isUsed; [ObservableProperty] private bool canInput; [ObservableProperty] private bool isRunning; /// /// 选中的类别名称-元素 /// [ObservableProperty] private Dictionary> collection; [ObservableProperty] private int categoryCount; [ObservableProperty] private int modifyType; [ObservableProperty] private string foundText; [ObservableProperty] private string prefixText; [ObservableProperty] private string replaceText; [ObservableProperty] private string searchText; [ObservableProperty] private string separator = "-"; [ObservableProperty] private string suffixText; //[ObservableProperty] //private IList selectedItems; // ReSharper disable once ConditionIsAlwaysTrueOrFalse public bool CanModify => RenameItems != null && RenameItems.Any(item => item.IsSelected); //[ObservableProperty] //private bool? isAllItemsSelected; //partial void OnIsAllItemsSelectedChanged(bool? value) //{ // if (value.HasSetValue) // { // SelectAll(value.Value, RenameItems); // } //} public bool? IsAllItemsSelected { get { var selected = RenameItems?.Select(item => item.IsSelected).Distinct().ToList(); if (selected == null) { return false; } // selected.Count()== 1 ? selected.Single() : null 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) { item.IsSelected = collector.Any(e => e.GetTypeId() == item.ElementType.Id); } } } public Dictionary> GetCategoriesFromDocument() { var dict = doc.OfType() .Where( t => t.CanBeRenamed && t.CanBeDeleted && t.CanBeCopied && !string.IsNullOrEmpty(t.FamilyName) && t.Category is { CategoryType: CategoryType.Model or CategoryType.Annotation, } && !string.IsNullOrEmpty(t.Category?.Name)) .GroupBy(t => t.Category.Name) .ToDictionary(g => g.Key, g => g.ToList()); CategoryCount = dict.Count; return dict; //foreach (BuiltInCategory builtInCategory in Enum.GetValues(typeof(BuiltInCategory))) //{ // try // { // var types = new FilteredElementCollector(doc).OfCategory(builtInCategory).WhereElementIsElementType().Cast().ToList(); // if (types.Any() && types.Any(t => t.CanBeRenamed)) // { // var category = types.FirstOrDefault()!.Category; // if (category is { CategoryType: CategoryType.Model or CategoryType.Annotation, AllowsBoundParameters: true }) // { // var name = category.Name; // items.Add(builtInCategory, name); // } // } // } // catch (Exception) // { // //string name = Enum.GetName(typeof(BuiltInCategory), builtInCategory); // //TaskDialog.Show( "错误", $"{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); ModifyTypeName(); } /// /// 获取列表中所有条目的新名称 /// private void GetNewNames() { var selectedItems = RenameItems.Where(item => item.IsSelected); foreach (var renameItem in selectedItems) { var tempName = renameItem.OldTypeName; 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.NewTypeName = tempName; } } [RelayCommand] private void GetRenameItems(IList items) { if (items.Count == 0) { RenameItems = null!; CanInput = false; return; } List symbolItems = []; foreach (var item in items) { if (item is KeyValuePair> categoryItems) { foreach (var type in categoryItems.Value) { RenameTypeItem renameItem = new() { OldTypeName = type.Name, ElementType = type, CategoryName = categoryItems.Key, FamilyName = type.FamilyName }; symbolItems.Add(renameItem); } } } CanInput = symbolItems.Any(); RenameItems = symbolItems; foreach (var renameItem in RenameItems) { renameItem.PropertyChanged += (_, args) => { //所有选择属性更改,会触发 if (args.PropertyName == nameof(RenameTypeItem.IsSelected)) { //全选框的状态 OnPropertyChanged(nameof(IsAllItemsSelected)); //foreach (RenameTypeItem item in SelectedItems) //{ // item.IsSelected = renameItem.IsSelected; //} ModifyNameCommand.NotifyCanExecuteChanged(); if (string.IsNullOrEmpty(renameItem.NewTypeName)) { GetNewNames(); } } //if (args.PropertyName == nameof(RenameTypeItem.NewTypeName)) //{ // ModifyTypeName(); //} }; } //IsAllItemsSelected = true; } private void ModifyTypeName() { var needToRename = RenameItems.Where(item => item.IsSelected); doc.Invoke( ts => { var sb = new StringBuilder(); foreach (var renameItem in needToRename) { try { if (!string.IsNullOrEmpty(renameItem.NewTypeName) && renameItem.OldTypeName != renameItem.NewTypeName) { renameItem.ElementType.Name = renameItem.NewTypeName; renameItem.OldTypeName = renameItem.NewTypeName; } } catch (Exception ex) { sb.AppendLine($"{renameItem.OldTypeName}-{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; } } }