Determine if Feature is Versioned

745
9
Jump to solution
04-23-2019 10:43 AM
BrianBulla
Occasional Contributor III

Hi,

I'm creating an Editor Extension and in my Events.OnChangeFeature I need to determine if the current feature being edited is Versioned.  How do I do this??  Currently my code crashes at the casting of the IFeature to IVersionedObject3.

        //Invoked when a feature is created or modified.
        void Events_OnCreateChangeFeature(ESRI.ArcGIS.Geodatabase.IObject obj)
        {
            try
            {
                IFeature inFeature = (IFeature)obj;
                
                IVersionedObject3 vObject = (IVersionedObject3)inFeature;

                if (vObject.IsRegisteredAsVersioned)
                    if (inFeature.Fields.FindField("LASTUSER") != -1 && inFeature.Fields.FindField("DATEMODIFIED") != -1)
                    {
                        MessageBox.Show("Versioned....this will be edited.");
                        return;
                    }
                    else
                    {
                        MessageBox.Show("Fields not found");
                        return;
                    }

                MessageBox.Show("Not versioned!!");
                return;                
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
1 Solution

Accepted Solutions
BrianBulla
Occasional Contributor III

This seems to work.  If you know of a better way to do this, or see issues with this, please let me know.

                IFeature inFeature = (IFeature)obj;
                ITable inTable = obj.Table;
                IVersionedObject3 vObject = (IVersionedObject3)inTable;

                if (vObject.IsRegisteredAsVersioned)
                    if (inFeature.Fields.FindField("LASTUSER") != -1 && inFeature.Fields.FindField("DATEMODIFIED") != -1)
                    {
                        MessageBox.Show("Fields found....this will be edited.");
                        return;
                    }
                    else
                    {
                        MessageBox.Show("Fields not found");
                        return;
                    }

View solution in original post

0 Kudos
9 Replies
BrianBulla
Occasional Contributor III

This seems to work.  If you know of a better way to do this, or see issues with this, please let me know.

                IFeature inFeature = (IFeature)obj;
                ITable inTable = obj.Table;
                IVersionedObject3 vObject = (IVersionedObject3)inTable;

                if (vObject.IsRegisteredAsVersioned)
                    if (inFeature.Fields.FindField("LASTUSER") != -1 && inFeature.Fields.FindField("DATEMODIFIED") != -1)
                    {
                        MessageBox.Show("Fields found....this will be edited.");
                        return;
                    }
                    else
                    {
                        MessageBox.Show("Fields not found");
                        return;
                    }
0 Kudos
by Anonymous User
Not applicable

Hey Brian,

Yep thats the right way to do it. The Object in IVersionedObject3 is an object class meaning a table or dataset etc.

0 Kudos
BrianBulla
Occasional Contributor III

Thanks Sean Jones‌,

The main issue I am having is getting around this line of code:  IFeature inFeature = (IFeature)obj;

This causes problems when an edit in a Table or something that isn't a 'Feature' occurs.  Currently I'm just wrapping a Try...Catch around it, but is there a better way to do this??  With the help you gave me with the ArcGIS Pro version of this tool I am creating, I was able to subscribe to certain layers, but with ArcMap it looks like this code will run on any row edit/Create.  Is that right??

        protected override void OnStartup()
        {
            IEditor theEditor = ArcMap.Editor;

            Events.OnStartEditing += new IEditEvents_OnStartEditingEventHandler(Events_OnStartEditing);
            Events.OnStopEditing += new IEditEvents_OnStopEditingEventHandler(Events_OnStopEditing);
        }

        void Events_OnStartEditing()
        {
            //Since features of shapefiles, coverages, and so on, cannot be validated, ignore wiring 
            //events for them.
            if (ArcMap.Editor.EditWorkspace.Type !=
                esriWorkspaceType.esriFileSystemWorkspace)
            {
                //Wire OnCreateFeature edit event.
                Events.OnCreateFeature += new IEditEvents_OnCreateFeatureEventHandler
                    (Events_OnCreateChangeFeature);
                //Wire onChangeFeature edit event.
                Events.OnChangeFeature += new IEditEvents_OnChangeFeatureEventHandler
                    (Events_OnCreateChangeFeature);
            }
        }

        //Invoked when a feature is created or modified.
        void Events_OnCreateChangeFeature(ESRI.ArcGIS.Geodatabase.IObject obj)
        {
            try
            {
                IFeature inFeature = (IFeature)obj;

                        try
                        {
                            ITable inTable = obj.Table;
                            IVersionedObject3 vObject = (IVersionedObject3)inTable;

                            if (vObject.IsRegisteredAsVersioned)
                                if (inFeature.Fields.FindField("LASTUSER") != -1 && inFeature.Fields.FindField("DATEMODIFIED") != -1)
                                {
                                    //MessageBox.Show("Fields found....this will be edited.");
                                    inFeature.set_Value(inFeature.Fields.FindField("LASTUSER"), System.Security.Principal.WindowsIdentity.GetCurrent().Name);
                                    inFeature.set_Value(inFeature.Fields.FindField("DATEMODIFIED"), DateTime.Now.ToString());

                                    return;
                                }
                                else
                                {
                                    //MessageBox.Show("Fields not found");
                                    return;
                                }                            
                        }

                        catch (Exception ex)
                        {
                            //MessageBox.Show("Not versioned!!");
                            return;
                        }                        
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Not a valid Feature");
            }
        }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
by Anonymous User
Not applicable

Brian,

You could cast the object to IRow instead which would handle features and stand alone table rows. IFeature is just a convenience extension from IRow which gives you easier access to the shape.

The ArcMap events fire for every layer and table in the map. Its easier to setup than Pro but you have to filter through the results to get what you need. This also creates a lot of network traffic, for enterprise GDB's, hence why Pro subscribes on a layer basis.

by Anonymous User
Not applicable

Oh and if you want to know if an object is an IFeature you can

If (Obj is IFeature) then

...but im rusty at arcobjects.

BrianBulla
Occasional Contributor III

Yeah, this is the first time I've created a new tool in ArcObjects in years.  It's all so foggy and convoluted after working in ArcGIS Pro.

Thanks for your help!

0 Kudos
BrianBulla
Occasional Contributor III

Actually Sean Jones ...one more question for you.

In either ArcObjects or Pro, is it possible to determine which field/fields have changed in the edited row?  The RowChangedEventArgs event doesn't seem to get the specific.

0 Kudos
by Anonymous User
Not applicable

Hey Brian,

There are methods/properties to see what changes have been made to a particular field. There isn't really a list of fields that have changed but fields are easy to iterate through.

In ArcObjects:

Use IRowChanges to see if the value changed for a particular field. (cast from IRow)

You can get a lot of detail through IDataChangesEx. Read the related topic at the bottom on how to use it.

In Pro:

Use Row.HasValueChanged and Row.GetOriginalValue to see the changes.

There is no DataChangesEx yet but....its on the list.

BrianBulla
Occasional Contributor III

Yeah, I've been messing with GetOriginalValue, but HasValueChanged seems to be the better option.  I'll look into the ArcObjects stuff you suggested too.

Thanks again!

0 Kudos