setting layer definition query issue

1379
5
Jump to solution
01-25-2019 12:36 PM
mikeharol
New Contributor III

trying to set a definition query I typically do something like:

lyr.SetDefinitionQuery("ProjNum = 'S100075'");

Now however we seem to have a collection.  When I set the query like above it seems to work although the definition query is empty.  Is there another method in the SDK to create a "New definition query" to handle this? I would imagine each definition query would have a name property, definition property, an is active property. 

I look forward to your response as my code a lot of these calls.

Regards,

Mike

1 Solution

Accepted Solutions
NarelleChedzey
Esri Contributor

Hi Mike, 

A couple of things. 

Firstly you can continue to set the definition query on a layer by using the layer.SetDefinition call. It is saved and it will filter the layer records.    Test this by using the API to set an expression similar to 'OBJECTID > 5' and open the attribute table for that layer and see that not all your records are displayed. 

There is a bug in the DefinitionQuery tab on the Layer properties dialog which is not correctly displaying the definition query when you use the 'SetDefinition' call. 

This dialog (which changed at V2.3 to allow multiple definition queries)  now uses the DefinitionFilter properties as you suspected.   You can access the CIM definition for the layer to set theses properties. 

Here is the code snippet which will assign a new filter and make it the default   - this can replace your call to SetDefinition if you require. 

// must run on the MCT - use QueuedTask.Run

// get the CIM layer definition
var layerDef = fLayer.GetDefinition() as CIMFeatureLayer;
// get the table for the layer
var featureTable = layerDef.FeatureTable;

// get the current set of definition filters
var filters = featureTable.DefinitionFilterChoices?.ToList();
// they might be null, so create a new list
if (filters == null)
   filters = new List<CIMDefinitionFilter>();

// create a new filter
var filter = new CIMDefinitionFilter();
filter.Name = "my filter";
filter.DefinitionExpression = newExpression;

// add to the list
filters.Add(filter);

// assign filters back to the CIMDisplayTable
featureTable.DefinitionFilterChoices = filters.ToArray();

// also set DefinitionExpression, DefinitionExpressionName
// - these define the active definition filter
featureTable.DefinitionExpression = filter.DefinitionExpression;
featureTable.DefinitionExpressionName = filter.Name;

// write back to the CIM layer definition
fLayer.SetDefinition(layerDef);

Thanks for pointing out the bug with the SetDefinition call and the layer properties dialog.  We will be addressing this. 

We will also work on updating the images in the sample to reflect the changes made to the dialog.  And updating the sample to reflect the changes made at V2.3 to use DefinitionFilters. 

Regards

Narelle

View solution in original post

5 Replies
mikeharol
New Contributor III

So I thought I could be clearer on my question since there has been no response.  I am working with the new SDK 2.3.  I have looked at the new sample QueryBuilderControl.  The screenshots show the old definition control which is confusing.  It did provide some insight into the CIMDefinitionFilter. 
DefinitionFilter {ArcGIS.Core.CIM.CIMDefinitionFilter} ArcGIS.Core.CIM.CIMDefinitionFilter
DefinitionFilterChoices {ArcGIS.Core.CIM.CIMDefinitionFilter[0]} ArcGIS.Core.CIM.CIMDefinitionFilter[]

I am not able to figure out how to put this information in my feature layer.

0 Kudos
NarelleChedzey
Esri Contributor

Hi Mike, 

A couple of things. 

Firstly you can continue to set the definition query on a layer by using the layer.SetDefinition call. It is saved and it will filter the layer records.    Test this by using the API to set an expression similar to 'OBJECTID > 5' and open the attribute table for that layer and see that not all your records are displayed. 

There is a bug in the DefinitionQuery tab on the Layer properties dialog which is not correctly displaying the definition query when you use the 'SetDefinition' call. 

This dialog (which changed at V2.3 to allow multiple definition queries)  now uses the DefinitionFilter properties as you suspected.   You can access the CIM definition for the layer to set theses properties. 

Here is the code snippet which will assign a new filter and make it the default   - this can replace your call to SetDefinition if you require. 

// must run on the MCT - use QueuedTask.Run

// get the CIM layer definition
var layerDef = fLayer.GetDefinition() as CIMFeatureLayer;
// get the table for the layer
var featureTable = layerDef.FeatureTable;

// get the current set of definition filters
var filters = featureTable.DefinitionFilterChoices?.ToList();
// they might be null, so create a new list
if (filters == null)
   filters = new List<CIMDefinitionFilter>();

// create a new filter
var filter = new CIMDefinitionFilter();
filter.Name = "my filter";
filter.DefinitionExpression = newExpression;

// add to the list
filters.Add(filter);

// assign filters back to the CIMDisplayTable
featureTable.DefinitionFilterChoices = filters.ToArray();

// also set DefinitionExpression, DefinitionExpressionName
// - these define the active definition filter
featureTable.DefinitionExpression = filter.DefinitionExpression;
featureTable.DefinitionExpressionName = filter.Name;

// write back to the CIM layer definition
fLayer.SetDefinition(layerDef);

Thanks for pointing out the bug with the SetDefinition call and the layer properties dialog.  We will be addressing this. 

We will also work on updating the images in the sample to reflect the changes made to the dialog.  And updating the sample to reflect the changes made at V2.3 to use DefinitionFilters. 

Regards

Narelle

mikeharol
New Contributor III

So the code worked great, I will need to modify as you can see it keeps

adding to the query in my situation I will start from a new

List(); Easy enough. I will look forward to the fix.

For clarity, it looks to me that the last SetDefinition(layerDef) plays a

role in what the active definition is.

0 Kudos
mikeharol
New Contributor III

Thanks that did the trick.

0 Kudos
mikeharol
New Contributor III

So I refactored a little sticking it in a method and creating a  new List<CIMDefinitionFilter>();, here is the code

private void SetLayerDefinition(FeatureLayer fLayer, string defExpression)
{
var layerDef = fLayer.GetDefinition() as CIMFeatureLayer;
var featureTable = layerDef.FeatureTable;
//var filters = featureTable.DefinitionFilterChoices?.ToList();
//if (filters == null)
// filters = new List<CIMDefinitionFilter>();

var filters = new List<CIMDefinitionFilter>();

var filter = new CIMDefinitionFilter
{
Name = "my filter",
DefinitionExpression = defExpression
};

filters.Add(filter);
featureTable.DefinitionFilterChoices = filters.ToArray();
featureTable.DefinitionExpression = filter.DefinitionExpression;
featureTable.DefinitionExpressionName = filter.Name;

// write back to the CIM layer definition
fLayer.SetDefinition(layerDef);
}