using System.ComponentModel.DataAnnotations; using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; using Autodesk.Revit.UI; using Nice3point.Revit.Toolkit.External.Handlers; namespace Szmedi.RvKits.Civil; public partial class FloorFinishesViewModel : ObservableValidator { public FloorFinishesViewModel(List floorTypes) { FloorTypes = floorTypes; finishesHandler = new ActionEventHandler(); } private readonly ActionEventHandler finishesHandler; private double floorOffset; [Required] [Range(-6000, 6000, ErrorMessage = "输入偏移量值范围有误")] //[CustomValidation(typeof(FloorFinishesViewModel), nameof(ValidateFloorOffset))] public double FloorOffset { get => floorOffset; set { SetProperty(ref floorOffset, value, true); PlaceFloorCommand.NotifyCanExecuteChanged(); } } //自定义验证方法 //public static ValidationResult ValidateFloorOffset(string floorOffset, ValidationContext context) //{ // FloorFinishesViewModel instance = (FloorFinishesViewModel)context.ObjectInstance; // bool isValid = double.TryParse(floorOffset, out var _); // if (isValid) // { // return ValidationResult.Success; // } // return new("输入内容不是数值。"); //} [ObservableProperty] private bool rbAllRooms; [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(PlaceFloorCommand))] private FloorType selectedFloorType; private bool CanPlace => SelectedFloorType != null && !HasErrors; public IList FloorTypes { get; } private IEnumerable selectedRooms; [RelayCommand(CanExecute = nameof(CanPlace))] private void PlaceFloor() { finishesHandler.Raise(app => { UIDocument uidoc = app.ActiveUIDocument; GetRoomsToPlace(uidoc); CreateFloors(uidoc); }); } public void CreateFloors(UIDocument uidoc) { Document document = uidoc.Document; document.Invoke( _ => { foreach (Room room in selectedRooms) { if (room != null && room.UnboundedHeight != 0.0) { //UnitFormatUtils.TryParse(doc.GetUnits(), UnitType.UT_Length, FloorOffset, out double value); SpatialElementBoundaryOptions option = new() { SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish }; IList> blist = room.GetBoundarySegments(option); CurveArray curveArray = new(); foreach (BoundarySegment bs in blist[0]) { curveArray.Append(bs.GetCurve()); } Level level = document.GetElement(room.LevelId) as Level; if (curveArray.Size != 0) { document.Create .NewFloor(curveArray, SelectedFloorType, level, false) .get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM) .Set(FloorOffset / 304.8); } } } }, "房间饰面" ); } private void GetRoomsToPlace(UIDocument uidoc) { Document doc = uidoc.Document; selectedRooms = RbAllRooms ? ( from elem in new FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(typeof(SpatialElement)) let room = elem as Room select room ) : uidoc.Selection.PickElementsByRectangle(new GenericFilter(), "请框选以选择房间").OfType(); } }