How to add rule to existing view filter

How to add rule to existing view filter

floretti
Advocate Advocate
1,083 Views
8 Replies
Message 1 of 9

How to add rule to existing view filter

floretti
Advocate
Advocate

Hi all,

 

I've been stuck on this for a few hours now and I just can't work out how to add a rule to a view filter that exists. I'm calling GetElementFilter() on line 10 below, which can return two options: an ElementParameterFilter or an ElementLogicalFilter. I'm not too sure of the logic behind it but I'm getting an ElementLogicalFilter.

 

I'm then calling the GetFilters() [line 15] on my ElementLogicalFilter and adding a new filter to the list but I then need to pass that to SetElementFilter() [line 23] but that only takes one ElementFilter. What I am missing here and how complicated can this get???

 

Thanks for reading. I've already checked the 2024 documentation and done my research but I couldn't find any help for that.

 

var allFilters = new FilteredElementCollector(doc)
					.OfClass(typeof(ParameterFilterElement))
					.WhereElementIsNotElementType()
					.ToElements();

foreach (ParameterFilterElement filter in allFilters)
{
	if (filter.Name == "MyFilterName")
	{
		var existElemFilter = filter.GetElementFilter();

		if (existElemFilter is ElementLogicalFilter)
		{
			var existLogicalFilter = existElemFilter as ElementLogicalFilter;
			IList<ElementFilter> existElemFilters = existLogicalFilter.GetFilters();

			IList<ElementFilter> newPhaseFilter = new List<ElementFilter>()
			{
				new ElementParameterFilter(ParameterFilterRuleFactory.CreateEqualsRule(phaseCreatedPar.Id, viewPhasePar.AsElementId())) as ElementFilter
			};

			existElemFilters.Add(new LogicalAndFilter(newPhaseFilter));
			filter.SetElementFilter(existElemFilters); // this needs an ElementFilter, not a list of them
		}
	}
}

 

0 Likes
Accepted solutions (1)
1,084 Views
8 Replies
Replies (8)
Message 2 of 9

scgq425
Advocate
Advocate

@floretti :

in u code , u want to add a new rule to paramaterFilter , but u make no distinction the elementFilter or paramaterFilter ,  if u want use the view-filter and add new rule , just find the target paramaterFilter and set a new rule or replace it .

i think u want to add new filter to the target view , if not , u can post new detail for u problem:

```

var allFilters = new FilteredElementCollector(doc)
.OfClass(typeof(ParameterFilterElement))
.WhereElementIsNotElementType()
.ToElements();

foreach (ParameterFilterElement filter in allFilters)
{
if (filter.Name == "MyFilterName")
{
var newRule = ParameterFilterRuleFactory.CreateEqualsRule(phaseCreatedPar.Id, viewPhasePar.AsElementId())

var filetElement = new ElementParameterFilter(newRule);
filter.SetElementFilter(filetElement);
// view.AddFilter(filter.id) or not


}
}

```

LanHui Xu 徐兰辉
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Blog
LinkedIn
Revit/CAD Development | Steel Product Manager

EESignature

0 Likes
Message 3 of 9

floretti
Advocate
Advocate

@scgq425 Thank you for responding.

 

Unfortunately when you use SetElementFilter() you are replacing all existing filter rules by the one you created. I'm looking to add one new filter rule to the ones already existing without overwriting them. I'm basically trying to avoid having to create all filter rules again from scratch as this means I'll have to work out several variations as opposed to just adding a new filter rule to a set of existing, which would be much easier.

0 Likes
Message 4 of 9

scgq425
Advocate
Advocate

@floretti :

Hi , In u code , i was understand u want  to replace the target filter , if u want to create a new filter  , ignore the loop and add a new filter in the view , like :

var filterElement = ParameterFilterElement.Create(document, name, categeorys);
filterElement.SetRules(filterRules);
view.AddFilter(filterElement.Id);
document.Regenerate()

if u want to set the background or foreground , add this :
var overrideSettings = view.GetFilterOverrides(filterElement.Id);
overrideSettings.SetProjectionFillColor(GetDBColorFromMediaColor(dictionary.Values.ElementAt(i)));
overrideSettings.SetProjectionFillPatternId(PatternId(document));
view.SetFilterOverrides(filterElement.Id, overrideSettings);
view.SetFilterVisibility(filterElement.Id, true);

LanHui Xu 徐兰辉
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Blog
LinkedIn
Revit/CAD Development | Steel Product Manager

EESignature

0 Likes
Message 5 of 9

Moustafa_K
Collaborator
Collaborator

not sure that is what you meant, but from my understanding to your comment, I would say you can combine filters before submitting them to the filtercollector, see this example

var newRule1 = ParameterFilterRuleFactory.CreateEqualsRule(ElementId.InvalidElementId, ElementId.InvalidElementId);
var newRule2 = ParameterFilterRuleFactory.CreateEqualsRule(ElementId.InvalidElementId, ElementId.InvalidElementId);
var newRule3 = ParameterFilterRuleFactory.CreateEqualsRule(ElementId.InvalidElementId, ElementId.InvalidElementId);

var paramFilterPackage = new ElementParameterFilter([newRule1, newRule2, newRule3]);

var newRule21 = ParameterFilterRuleFactory.CreateEqualsRule(ElementId.InvalidElementId, ElementId.InvalidElementId);
var newRule22 = ParameterFilterRuleFactory.CreateEqualsRule(ElementId.InvalidElementId, ElementId.InvalidElementId);
var newRule23 = ParameterFilterRuleFactory.CreateEqualsRule(ElementId.InvalidElementId, ElementId.InvalidElementId);

var paramFilterPackage2 = new ElementParameterFilter([newRule21, newRule22, newRule23]);

var logicFilter = new LogicalOrFilter(paramFilterPackage, paramFilterPackage2);

var collectedFilter = new FilteredElementCollector(Doc)
    .OfClass(typeof(ParameterFilterElement))
    .WhereElementIsNotElementType()
    .WherePasses(logicFilter)
    .ToElements();
Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
Message 6 of 9

floretti
Advocate
Advocate

@scgq425 As much as I appreciate your replies and the code snippets I have no issues with creating and adding a filter to my view or override its visibility. My issue is with changing an existing view filter and adding an extra rule to it without removing the existing rules.

 

@Moustafa_K I probably should've put that part into my original post, my bad. I have existing projects with view filters already applied to view templates (already applied to views) and I need to add an extra rule to some of those existing view filters. I'll try your suggestion anyway as it's likely to work, thank you.

0 Likes
Message 7 of 9

scgq425
Advocate
Advocate

hi @floretti :

i understander u requirement , in this code , i changed the target level rule which name "Sample" from " L1 - Block 35" to "Parking" , i think this is u target :

 

var document = RevitCommandData.Document;
var collector = document.ElementCollector(typeof(ParameterFilterElement));

TransactionUtils.Execute(document, x =>
{
var targetFilter = collector.Where(f => f.Name.Contains("Sample")).Cast<ParameterFilterElement>().ToList().First();
targetFilter.ClearRules();

var paraId = new ElementId(-1001107);
var newRule = ParameterFilterRuleFactory.CreateEqualsRule(paraId, new ElementId(1363065));
targetFilter.SetElementFilter(new ElementParameterFilter(newRule));
},"Sample");

LanHui Xu 徐兰辉
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Blog
LinkedIn
Revit/CAD Development | Steel Product Manager

EESignature

0 Likes
Message 8 of 9

floretti
Advocate
Advocate

@scgq425 Thanks again. You cleared the rules and added the new one in. I need to leave the existing rule there and add a new one without removing the existing rule.

 

I did manage to add a new set of rules using the code below but now I'll try and work out how to add a new rule to the existing set.

// Create new rule
IList<ElementFilter> newPhaseFilter = new List<ElementFilter>()
{
	new ElementParameterFilter(ParameterFilterRuleFactory.CreateEqualsRule(phaseCreatedPar.Id, viewPhasePar.AsElementId())) as ElementFilter
};

// Collect existing rules
var existLogicalFilter = existElemFilter as ElementLogicalFilter;
IList<ElementFilter> existElemFilters = existLogicalFilter.GetFilters();

// Add new rule to existing set of rules
foreach (ElementParameterFilter elemFilter in existElemFilters)
{
	existRules = elemFilter.GetRules();
	var ruleParam = doc.GetElement(existRules.First().GetRuleParameter())?.Name;
	if (existRules.Count == 1 && ruleParam == "Condition")
		existRules.Add(ParameterFilterRuleFactory.CreateEqualsRule(phaseCreatedPar.Id, viewPhasePar.AsElementId()));
}

var newElemFilter = new ElementParameterFilter(existRules);
filter.SetElementFilter(newElemFilter);

 

0 Likes
Message 9 of 9

floretti
Advocate
Advocate
Accepted solution

Ok, line 6 below did the job.

 

var existLogicalFilter = existElemFilter as ElementLogicalFilter;
IList<ElementFilter> existElemFilters = existLogicalFilter.GetFilters();

var newRule = ParameterFilterRuleFactory.CreateEqualsRule(phaseCreatedPar.Id, viewPhasePar.AsElementId());
var newElemFilter = new ElementParameterFilter(newRule);
var newLogicalFilter = new LogicalAndFilter(existElemFilters.First(), newElemFilter);
filter.SetElementFilter(newLogicalFilter);