Trying this as a Question instead of a Discussion.
I'm having trouble getting a QueryTable to display. The tool selects a single sewer line, gets the feature ID for the line (called COMPKEY), then uses the ID to build the where clause and hopefully open the query table.
What am I missing?
protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
Uri path = new Uri("O:\\P\\A\\T\\H\\CONNECTION.sde");
return QueuedTask.Run(() =>
{
ActiveMapView.SelectFeatures(geometry, SelectionCombinationMethod.New);
string slComp = Module1.GetCompkey();
if (!string.IsNullOrEmpty(slComp))
{
// Set up Geodatabase Object)
using (Geodatabase geodatabase = new Geodatabase(new DatabaseConnectionFile(path)))
{
string queryString = $"COMPKEY = {slComp}";
QueryDef queryDef = new QueryDef()
{
Tables = "SDE.TABLE.NAME",
WhereClause = queryString,
};
QueryTableDescription queryTableDescription = new QueryTableDescription(queryDef)
{
MakeCopy = true,
Name = $"Preventive Maintenance: {slComp}.",
PrimaryKeys = geodatabase.GetSQLSyntax().QualifyColumnName("SDE.sewerman.tblV8PMTOOL", "COMPKEY")
};
var queryTable = geodatabase.OpenQueryTable(queryTableDescription);
int count = queryTable.GetCount();
if (count == 0)
{
MessageBox.Show("Sewer line selected has no preventive maintenance scheduled.");
}
else
{
// Used since query table doesn't display
// MessageBox.Show($"Row count: {count}");
}
}
};
Brad,
Do you know where this code is failing? Have you stepped through with a debugger to see the value of count?
You state: "I'm having trouble getting a QueryTable to display." At the risk to taking your question too literally, you haven't included any code to display a QueryTable, just to create one. Is that the issue? (If so, do you want this to display as a table view or a layer on your map)
--Rich
Yes, that is the issue. I couldn't find any snippits/examples on how to do this.
Brad-
I'm not an expert on using the ArcGIS Pro Content classes, but I think this code should do it:
// Create a standalone table from the queryTable Table
IStandaloneTableFactory tableFactory = StandaloneTableFactory.Instance;
StandaloneTable standaloneTable = tableFactory.CreateStandaloneTable(queryTable, MapView.Active.Map);
// Open the standalone table into a window
FrameworkApplication.Panes.OpenTablePane(standaloneTable, TableViewMode.eAllRecords);
--Rich
Thanks, for your help, Rich. But the following method must be called on the UI thread.
FrameworkApplication.Panes.OpenTablePane(standaloneTable, TableViewMode.eAllRecords);
That's correct, Brad. You'll need to restructure your code so that the QueryTable is called on the MCT (main CIM thread) using QueuedTask, and you create the standalone table on the UI thread.
Unfortunately, because of my own inadequacies as a .Net developer, I can't figure out how to display—OpenTablePane— the standalone table from the UI thread. I'm missing something.
I think I'll try to do it in a DockPane. It's not ideal for this situation, but there seems to be plenty of code examples for this.
Thanks for your help, Rich.
Hi Brad, so here are some possibilities:
Option 1: Make the table and return the table from the QueuedTask and show it
internal class OpenTableButton : Button
{
protected async override void OnClick()
{
//capture the active map
var theMap = MapView.Active.Map;
//option 1 - return the table from the QueuedTask
var table = await QueuedTask.Run(() =>
{
return StandaloneTableFactory.Instance.CreateStandaloneTable(
new Uri(@"Path_To_File_GDB.gdb\EarthquakeDamage_Table",
UriKind.Absolute),
theMap);
});
FrameworkApplication.Panes.OpenTablePane(table);
}
}
Option 2: Make the table and show it from the QueuedTask (the syntax to do that is a bit gnarly I must confess)...still...it is here if you need it
internal class OpenTableButton : Button
{
protected async override void OnClick()
{
//capture the active map
var theMap = MapView.Active.Map;
//option 2 - invoke the OpenTablePane on the UI thread from
//~within~ the QueuedTask
await QueuedTask.Run(() =>
{
var table2 = StandaloneTableFactory.Instance.CreateStandaloneTable(
new Uri(@"Path_to_File_GDB.gdb\Meteorites_UK_Table",
UriKind.Absolute),
theMap);
//now put us on the UI thread to open the table pane
FrameworkApplication.Current.Dispatcher.BeginInvoke((Action)(() =>
{
FrameworkApplication.Panes.OpenTablePane(table2);
}));
});
}
}
Option 3: Make the table on the QueuedTask. Return from the QueuedTask. Retrieve the table from the Map (on the UI) and show it. This would be akin to how you would retrieve a table from the TOC that had previously been added.
internal class OpenTableButton : Button
{
protected async override void OnClick()
{
//capture the active map
var theMap = MapView.Active.Map;
//Create the table from the QueuedTask
await QueuedTask.Run(() =>
{
StandaloneTableFactory.Instance.CreateStandaloneTable(
new Uri(@"Path_To_File_GDB.gdb\EarthquakeDamage_Table",
UriKind.Absolute),
theMap);
});
//option 3...get the table from the map after it has been added...
var table3 = theMap.FindStandaloneTables("EarthquakeDamage_Table").First();
FrameworkApplication.Panes.OpenTablePane(table3);
}
}
Thanks for the snippets, Charles. But the problem I was having was trying to open the table without the user having to go to the ribbon click another button. I want them to click on a tool to activate, click on a feature, and the table opens with the subset of data.
Thanks for your help.
I just want to point out that this was the solution I was looking for.
I did not want the users to have to click a second bottom to open the table. I wanted it to run in OnSketchCompleteAsync method.
protected override async Task<bool> OnSketchCompleteAsync(Geometry geometry) { var standaloneTable = await QueuedTask.Run(() => { ActiveMapView.SelectFeatures(geometry, SelectionCombinationMethod.New); slComp = Module1.GetCompkey(); if (!string.IsNullOrEmpty(slComp)) { Uri path = new Uri("\\P\\A\\T\\H.sde"); // Set up Geodatabase Object) using (Geodatabase geodatabase = new Geodatabase(new DatabaseConnectionFile(path))) { string queryString = $"COMPKEY = {slComp}"; QueryDef queryDef = new QueryDef() { Tables = "SDE.sewerman.tblV8PMTOOL", WhereClause = queryString, }; QueryTableDescription queryTableDescription = new QueryTableDescription(queryDef) { MakeCopy = true, Name = $"Preventive Maintenance: {slComp}", PrimaryKeys = geodatabase.GetSQLSyntax().QualifyColumnName("SDE.CONNECTION", "COMPKEY") }; var queryTable = geodatabase.OpenQueryTable(queryTableDescription); int count = queryTable.GetCount(); if (count == 0) { MessageBox.Show("Sewer line selected has no preventive maintenance scheduled."); } else { // Create a standalone table from the queryTable Table IStandaloneTableFactory tableFactory = StandaloneTableFactory.Instance; StandaloneTable pmTable = tableFactory.CreateStandaloneTable(queryTable, MapView.Active.Map); return pmTable; } } }; //return base.OnSketchCompleteAsync(geometry); return null; }); // Open the standalone table pane FrameworkApplication.Panes.OpenTablePane(standaloneTable, TableViewMode.eAllRecords); return true; }