IFeatureLayer.FeatureClass returning null

2039
16
08-18-2011 12:04 PM
RodrigoSalvador
New Contributor
Hi everyone

This might be a simple doubt. When opening a single .mxd, I can read correctly some properties of the layer, like Name and DataSourceType. When I try to access the FeatureClass, it always returns null. Checking the source inside ArcMap, the FeatureClass is there just as I want. So, why can't I read it programatically?

Here's the relevant part of the code:

namespace WindowsApplication1
{
  public partial class Form1 : Form
  {
    private IMapDocument pMapDocument = null;
    private IMap pMap = null;
    private IEnumLayer pEnumLayer = null;
    private IFeatureLayer pFeatureLayer = null;
    private IDataLayer2 pDataLayer = null;
    private IDatasetName pDatasetName = null;
    private IWorkspace pWorkspace = null;
    private IWorkspaceName pWorkspaceName = null;
    private IUID pUID = null;
    private string p = "password";

    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Shown(object sender, EventArgs e)
    {
      Application.DoEvents();
      Start("", true);
    }

    private void Start(string sPath, bool inicializando)
    {
      bool saveInsideLayer = true;
      int i;
      string mxd;

      IPropertySet pConnectionProperties = new PropertySetClass();

      if (sPath == "")
      {
        saveInsideLayer = false;
        sPath = @"C:\layer.mxd";
      }

      try
      {
        pMapDocument = new MapDocumentClass();
        if (pMapDocument.get_IsPresent(sPath))
        {
          pMapDocument.Open(sPath, "");
        }
        
        for (i = 0; i < pMapDocument.MapCount; i++)
        {
          pMap = pMapDocument.get_Map(i);

          pUID = new UIDClass();
          pUID.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}"; 
          pEnumLayer = pMap.get_Layers((UID)pUID, true);

          pEnumLayer.Reset();
          pFeatureLayer = (IFeatureLayer)pEnumLayer.Next();

          while (pFeatureLayer != null)
          {
            if (pFeatureLayer.DataSourceType.Contains("SDE"))
            {
              pDataLayer = (IDataLayer2)pFeatureLayer;
              if (pDataLayer.DataSourceName is IDatasetName)
              {
                pDatasetName = (IDatasetName)pDataLayer.DataSourceName;
                pWorkspaceName = pDatasetName.WorkspaceName;
                if (pFeatureLayer.FeatureClass != null) // why never true?
                {
                  pConnectionProperties = pFeatureLayer.FeatureClass.ExtensionProperties; 
                }

                pWorkspaceName.ConnectionProperties = pConnectionProperties;
              }
            }
            pFeatureLayer = (IFeatureLayer)pEnumLayer.Next();
          }

          txtServidor.Text = pConnectionProperties.GetProperty("SERVER").ToString();
          txtPorta.Text = pConnectionProperties.GetProperty("INSTANCE").ToString();
          txtDatabase.Text = pConnectionProperties.GetProperty("DATABASE").ToString();
          txtUsuario.Text = pConnectionProperties.GetProperty("USERNAME").ToString();
          txtSenha.Text = pConnectionProperties.GetProperty("PASSWORD").ToString();

          if (saveInsideLayer)
          {
            pMapDocument.ReplaceContents((IMxdContents)pMap);
            pMapDocument.Save();
            pMapDocument.Close();
          }
        }
      }
      catch (Exception ex)
      {
        throw new Exception("Unable to run the code", ex);
      }
    }

  }
}


I'm working in Visual Studio 2005, and using an ArcInfo license for 9.3 version.

Thanks for the attention

Rodrigo Salvador
0 Kudos
16 Replies
AlexanderGray
Occasional Contributor III
Strange...  The MapDocument help says:

"Remarks
When opening or creating a map document with the IMapDocument Open() or New() methods, you should always make subsequent calls to IActiveView::Activate() in order to properly initialize the display of the PageLayout and Map objects.  Call Activate() once for the PageLayout and once for each Map you will be working with.  If your application has a user interface, you should call Activate() with the hWnd of the application's client area.  If your application runs in the background and has no windows, you can always get a valid hWnd from the GDI GetDesktopWindow() function, part of the Win32 API."

Have you tried the activate method call?
0 Kudos
RodrigoSalvador
New Contributor
Alexander

To change the layer's properties, I think I don't need to open the ArcMap (at least, I'm not dealing with this option). So, the ActiveView is not necessary. Even way, I called Activate() for testing, and it makes no difference.

I've found a code that updates the information without connecting. I don't have it here right now, sorry, but it's something like "pWorkspaceName.ConnectionPropperties = pPropSet" after setting the pPropSet properly. It runs fine, but the information inside the layer did not change. Aldo, that .Save(true,false) is crashing the application. I couldn't understand how to set the parameters here.

Thanks for your time

Rodrigo Salvador
0 Kudos
AlexanderGray
Occasional Contributor III
I am getting similar behaviour on a 10.0 SP2 machine.  10.0 SP1 seem to work ok...
0 Kudos
RodrigoSalvador
New Contributor
Hello Alexander

Based on my application, I can only ask if you really need do use the IFeatureLayer.FeatureClass property. At this point, everything is going ok for me (reading the layer properties, changing and then saving), except for a DataSource connection (I am not able to open correctly the .mxd after saving, though the properties are correct. The spatial references are missing after saving). This means the null value in FeatureClass makes no difference for me at all.

I presume that's nothing wrong with your code.

Sincerely

Rodrigo Salvador
0 Kudos
AlexanderGray
Occasional Contributor III
I need to access the workspace name.  That is returning null too but not on my development machine and only when it is called from a form, if I call it from a command it works ok...
0 Kudos
RodrigoSalvador
New Contributor
Alexander,

I had some troubles with IWorkspaceName.PathName too. It was loading a path that doesn't exist on my machine, but on the developer's. I solved that using IWorkspaceName. Did you try it?

Rodrigo Salvador
0 Kudos
AlexanderGray
Occasional Contributor III
turns out it was a bad mxd causing the problem
0 Kudos