ArcObjects – Specify a Starting Location with IgxDialog

arcobjects

I would like to know what is the easiest way to set the starting location of a data dialog to a IWorkspace?

My problem is that basically I do not want a connection (.sde file) for the users. I want to set the starting location to a workspace connected via IPropertySet. Is it possible?

This is related: Force a new AddDataDialog to open at a defined directory path but does not help.

EDIT:

following Kirk's suggestion, here's a code snippet. This does not work.

    public static IDataset OpenDatasetDialog(IWorkspace workspace,int handle)
    {
        var workspaceName = (IWorkspaceName)((IDataset)workspace).FullName);
        var gxDatabase = new GxdatabaseClass();
        gxDatabase.WorkspaceName = workspaceName;

        // we need to set a different variable as .NET runtime does not allow ref parameters with casts
        object gxObj = (object)gxDatabase;

        IGxDialog openDialog = new GxDialogClass();
        openDialog.RememberLocation = false;
        openDialog.set_StartingLocation(ref gxObj);
        var filterColletion = (IGxObjectFilterCollection)openDialog;
        filterColletion.AddFilter(new GxFilterTablesAndFeatureClassesClass(), true);
        openDialog.AllowMultiSelect = false;
        IEnumGxObject datasets = null;
        IDataset dataset = null;

        if (openDialog.DoModalOpen(0, out datasets) && datasets != null)
        {
            IGxObject gxObject = datasets.Next();
            if (gxObject is IGxDataset)
            {
                IGxDataset gxDataset = (IGxDataset)gxObject;
                dataset = gxDataset.Dataset;
            }
            else
                throw new ArgumentException();
        }
        openDialog.InternalCatalog.Close();
        return dataset;
    }

Best Answer

Kirk's answer is on the right track. The only thing missing is properly adding the GxDatabase into the dialog's internal catalog tree.

See the code below. The OpenGxDialogForRemoteWorkspace returns an enumerable of selected objects (if multiselect is allowed) or null in case the dialog is cancelled. It's very basic since I omitted the object filters you used, but I think you get the idea.

    private static IEnumerable<IGxObject> OpenGxDialogForRemoteWorkspace(IWorkspaceName workspaceName, int handle)
    {
        if (workspaceName == null) throw new ArgumentNullException("workspaceName");
        if (workspaceName.Type != esriWorkspaceType.esriRemoteDatabaseWorkspace)
        {
            throw new ArgumentException("Remote worskpace is expected.", "workspaceName");
        }

        var gxDatabase = new GxDatabaseClass();
        gxDatabase.WorkspaceName = workspaceName;

        var gxDialog = new GxDialogClass();
        var catalog = gxDialog.InternalCatalog;

        var topLevelCatalogItems = AsEnumerable(((IGxObjectContainer)catalog).Children);
        var remoteDatabaseFolder = topLevelCatalogItems.OfType<IGxRemoteContainer>().First();

        ((IGxObjectContainer)remoteDatabaseFolder).AddChild(gxDatabase);

        gxDialog.RememberLocation = false;

        object gxDatabaseObject = gxDatabase;
        gxDialog.set_StartingLocation(ref gxDatabaseObject);

        IEnumGxObject selection;
        if (gxDialog.DoModalOpen(handle, out selection))
        {
            return selection != null ? AsEnumerable(selection) : null;
        }

        return null;
    }

    private static IEnumerable<IGxObject> AsEnumerable(IEnumGxObject enumGxObject)
    {
        if (enumGxObject == null) throw new ArgumentNullException("enumGxObject");
        enumGxObject.Reset();

        IGxObject gxObject;
        while ((gxObject = enumGxObject.Next()) != null)
        {
            yield return gxObject;
        }
    }
Related Question