/// <summary> /// Update ParameterFilterElements in the Revit document with data from the dialog box. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void okButton_Click(object sender, EventArgs e) { // Reserve how many Revit filters need to be updated/removed ICollection <String> updatedFilters = new List <String>(); ICollection <ElementId> deleteElemIds = new List <ElementId>(); FilteredElementCollector collector = new FilteredElementCollector(m_doc); ICollection <Element> oldFilters = collector.OfClass(typeof(ParameterFilterElement)).ToElements(); // // Start transaction to update filters now Transaction tran = new Transaction(m_doc, "Update View Filter"); tran.Start(); try { // 1. Update existing filters foreach (ParameterFilterElement filter in oldFilters) { FilterData filterData; bool bExist = m_dictFilters.TryGetValue(filter.Name, out filterData); if (!bExist) { deleteElemIds.Add(filter.Id); continue; } // // Update Filter categories for this filter ICollection <ElementId> newCatIds = filterData.GetCategoryIds(); if (!ListCompareUtility <ElementId> .Equals(filter.GetCategories(), newCatIds)) { filter.SetCategories(newCatIds); } // Update filter rules for this filter IList <FilterRule> newRules = new List <FilterRule>(); foreach (FilterRuleBuilder ruleData in filterData.RuleData) { newRules.Add(ruleData.AsFilterRule()); } ElementFilter elemFilter = FiltersUtil.CreateElementFilterFromFilterRules(newRules); // Set this filter's list of rules. filter.SetElementFilter(elemFilter); // Remember that we updated this filter so that we do not try to create it again below. updatedFilters.Add(filter.Name); } // // 2. Delete some filters if (deleteElemIds.Count > 0) { m_doc.Delete(deleteElemIds); } // // 3. Create new filters(if have) foreach (KeyValuePair <String, FilterData> myFilter in m_dictFilters) { // If this filter was updated in the previous step, do nothing. if (updatedFilters.Contains(myFilter.Key)) { continue; } // Create a new filter. // Collect the FilterRules, create an ElementFilter representing the // conjunction ("ANDing together") of the FilterRules, and use the ElementFilter // to create a ParameterFilterElement IList <FilterRule> rules = new List <FilterRule>(); foreach (FilterRuleBuilder ruleData in myFilter.Value.RuleData) { rules.Add(ruleData.AsFilterRule()); } ElementFilter elemFilter = FiltersUtil.CreateElementFilterFromFilterRules(rules); // Check that the ElementFilter is valid for use by a ParameterFilterElement. IList <ElementId> categoryIdList = myFilter.Value.GetCategoryIds(); ISet <ElementId> categoryIdSet = new HashSet <ElementId>(categoryIdList); if (!ParameterFilterElement.ElementFilterIsAcceptableForParameterFilterElement( m_doc, categoryIdSet, elemFilter)) { // In case the UI allowed invalid rules, issue a warning to the user. MyMessageBox("The combination of filter rules is not acceptable for a View Filter."); } else { ParameterFilterElement.Create(m_doc, myFilter.Key, categoryIdSet, elemFilter); } } // // Commit change now tran.Commit(); } catch (Exception ex) { String failMsg = String.Format("Revit filters update failed and was aborted: " + ex.ToString()); MyMessageBox(failMsg); tran.RollBack(); } }