|
POST
|
In theory you can use this snippet: // Test_EditBox is the Id of the editBox in config.daml:
var plugin = FrameworkApplication.GetPlugInWrapper ("Test_EditBox"); however, currently there is a limitation in the API that doesn't allow you to access the returned plugin wrapper which is of the type: ArcGIS.Desktop.Framework.Wrappers.EditBoxWrapper, not accessible via the API. So the best way to access the text from anywhere is to create a static string property in the Module class and set that property with the text each time the text is changed: Module1.cs add: internal static string EditText { get; set; } To your EditBox class you add these overrides depending on your input trigger preference: /// <summary>
/// Called when the 'Enter' key is pressed inside this control or when the control loses keyboard focus.
/// </summary>
protected override void OnEnter()
{
// Passes the current Text in the EditBox to the global parameter in Module1.
Module1.EditText = Text;
}
protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
// Passes the current Text in the EditBox to the global parameter in Module1.
Module1.EditText = Text;
} If you prefer events you can also implement an OnEditBoxChanged event in you EditBox class.
... View more
05-07-2020
10:31 AM
|
2
|
2
|
2011
|
|
POST
|
In the setter for the MyAppDataDir property in the ViewModel set base.IsValid: // for example
public string MyAppDataDir
{
get { return _myAppDataDir; }
set
{
SetProperty(ref _myAppDataDir, value, () => MyAppDataDir);
base.IsValid = System.IO.Directory.Exists(value);
}
}
... View more
05-06-2020
03:43 PM
|
0
|
7
|
4024
|
|
POST
|
Hi Victor, I used Pro 2.5 and I attached my zip'ed sample project. If you change the desktop version attribute in config.daml you should be able to build the add-in for 2.4, 2.3 as well.
... View more
05-06-2020
10:41 AM
|
1
|
1
|
2730
|
|
POST
|
I have problems with this feature too. It doesn't work for me when I reply through the Notification list in my geonet inbox (this might be fixed by now ... I haven't tried it in years), but I get it to work once I navigate to the geonet question link (by clicking on the geonet question). From the geonet question link, you click "Reply" and then you click on the "..." menu in you reply edit menu bar, that opens up more options. Next you click the "More" pull-down and choose syntax highlighter. In the syntax highlighter popup choose the format from the pull down and paste the text. The text will be highlighted to make code and xml more readable. you can also use Ctrl+V to paste an image from your clipboard.
... View more
05-04-2020
01:57 PM
|
0
|
0
|
9256
|
|
POST
|
There are multiple examples in the Pro SDK community samples repo that are displaying a DataTable in a DataGrid control. You can use the GitHub search, on the top left on the Pro SDK community samples repo page, to search for the term "DataTable" to find all samples. For example: Map-Exploration IdentifyWindow is using a DataTable to autogenerate columns and display a table. As Than mentioned in the reply above you need to call either NotifyPropertyChanged("...") or you can also define your DataTable property with a setter that calls SetProperty(...). Both NotifyPropertyChanged and SetProperty notify the UI that the DataTable property changed causing the UI to update its content. So your ViewModel property would look like this: private DataTable _intersectionDataTable = new DataTable();
public DataTable IntersectionDataTable
{
get { return _intersectionDataTable; }
set
{
SetProperty(ref _intersectionDataTable, value, () => IntersectionDataTable);
}
} You XAML should look like this: <DataGrid Grid.Row="1" Margin="5" Name="selectedFeatureGrid"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
Style="{DynamicResource Esri_DataGrid}"
AutoGenerateColumns="True"
HorizontalAlignment="Stretch"
HeadersVisibility="Column"
RowHeaderWidth="0"
IsReadOnly="True"
SelectionMode="Single"
SelectedItem="{Binding Path=SelectedIntersectionRow}"
ItemsSource="{Binding Path=IntersectionDataTable, Mode=OneWay}" >
</DataGrid> And to update / change the DataTable in your code you would have to first define the new DataTable and then call the DataTable's ItemSource property's setter: // note: all columns are string types, listColumnNames contains the name for each column
// and listValues contains a list of strings for each row
var newDataTable = new DataTable();
foreach (var col in listColumnNames) {
newDataTable.Columns.Add(new DataColumn(col.Key, typeof(string)) { Caption = col.Value });
}
foreach (var row in listValues) {
var newRow = newDataTable.NewRow();
newRow.ItemArray = row.ToArray();
newDataTable.Rows.Add(newRow);
}
// set the new property and notify the UI
// this Update has to be made from the UI thread
IntersectionDataTable = newDataTable; Make sure that you call the IntersectionDataTable setter from the UI thread (Note that this is true for all properties that are databound to WPF controls).
... View more
05-04-2020
10:18 AM
|
0
|
1
|
9256
|
|
POST
|
Hi Abel, Since this seems to be a common question, let me elaborate a bit. Maybe this will also help others looking at this post. MVVM is an architectural programming pattern that is used in most WPF based large scale or enterprise systems. I think in the long run a good understanding on what it does will make programming using MVVM a lot easier. I used WinForms for many years (if not decades) and it took me a while to get used to MVVM but after I got my head around it, I actually prefer it now. If you have some time maybe you can look at this YouTube: WPF: why MVVM? The video explains the "why?", but also looks a bit behind the curtain of MVVM. Specifically to answer your question: controlling the visibility of controls on your dockpane: Since you already know that you need to bind the Visibility attribute of your UI control, I want to mention the approach that I often use when looking for a reference sample implementation: On the top left of the community samples github repo page I enter the text string for which I need a code snippet for (as specific as possible to reduce the number of candidates). So for your requirements I searched for 'Visibility="{Binding' (note: only search for this repo not all of Github): In similar fashion you can also search https://github.com/Esri/arcgis-pro-sdk because it contains the source for all ProSnippets. The search above yields all controls that are bound to some kind of 'visibility' property in my viewmodel. I open the "Samples" solution (from community samples) in Visual Studio and look at the located solutions there. In this case I search in Visual Studio for '<Grid Visibility="{Binding DockpaneVisibility}">' which yields the 'SymbolLookup' project. I open the ViewModel file: SymbolLookupDockpaneViewModel.cs and the View file: SymbolLookupDockpane.xaml. Databinding links the 'DockpaneVisibility' property: private Visibility _dockpaneVisibility;
/// <summary>
/// Controls the visible state of the controls on the dockpane
/// </summary>
public Visibility DockpaneVisibility
{
get { return _dockpaneVisibility; }
set { SetProperty(ref _dockpaneVisibility, value, () => DockpaneVisibility); }
} To this UI element: <Grid Visibility="{Binding DockpaneVisibility}"> Note that 'SetProperty(ref...' the DockpaneVisibility setter is required because this method will 'notify' the UI (via data binding) when the code changes the DockpaneVisibility property. To change your control's visibility you can use the following code snippets: // make the control bound to DockpaneVisibility invisible:
DockpaneVisibility = Visibility.Collapsed;
// make the control bound to DockpaneVisibility visible:
DockpaneVisibility = Visibility.Visible; Finally, and you see the code for this also in the ViewModel file: SymbolLookupDockpaneViewModel.cs: you can subscribe to the ActiveMapViewChangedEvent either in the constructor on in InitializeAsync: protected SymbolLookupDockpaneViewModel()
{
//either Subscribe to ActiveMapViewChangedEvent here:
ActiveMapViewChangedEvent.Subscribe(OnActiveMapViewChangedEvent);
}
protected override async Task InitializeAsync()
{
//or Subscribe to ActiveMapViewChangedEvent here:
ActiveMapViewChangedEvent.Subscribe(OnActiveMapViewChangedEvent);
} And your subscription logic could look like this (similar to the sample I found): /// <summary>
/// Event handler when the active MapView changes
/// </summary>
/// <param name="obj"></param>
private void OnActiveMapViewChangedEvent(ActiveMapViewChangedEventArgs obj)
{
if (obj.IncomingView == null)
{
// there is no active map view - disable the UI
DockpaneVisibility = Visibility.Collapsed;
return;
}
// we have an active map view - enable the UI
DockpaneVisibility = Visibility.Visible;
} Since this code will only kick in after your dockpane is instantiated (it's constructor is called), you need to set up the initial visibility state in the constructor: protected SymbolLookupDockpaneViewModel()
{
//setup the initial visibility state
DockpaneVisibility = MapView.Active != null ? Visibility.Visible : Visibility.Collapsed;
//either Subscribe to ActiveMapViewChangedEvent here:
ActiveMapViewChangedEvent.Subscribe(OnActiveMapViewChangedEvent);
} I hope this helps.
... View more
05-01-2020
01:23 PM
|
3
|
2
|
3030
|
|
POST
|
Hi Helen, I am attaching a sample project for you that demonstrates how to populate a listbox with two columns using the first two columns of a spreadsheet. I think this is a useful sample and I will add it with the next release to the community samples. The add-in looks for a .csv file that I included in the project source as well (it's called Meteorites_UK.csv). You can read any file that can be opened with Excel with this code but you have to match the sheet name and column count. To run the add-in, open the "Show Spreadsheet" dockpane, then use the "import csv" button to browse to Meteorites_UK.csv. Once you click "Open" on the input selection dialog you see the listbox getting populated. If you look at ShowSpreadsheet.xaml you find that the listview is bound to two properties: SpreadSheetRows for the ItemsSource and SelectedSpreadSheetRow for the SelectedItem attributes. If you then look in the code behind file ShowSpreadsheetViewModel.cs you see the appropriate properties that match these 'bindings': public ObservableCollection<SpreadSheetColumns> SpreadSheetRows and public SpreadSheetColumns SelectedSpreadSheetRow When you look at these properties you will notice that both are using 'SetProperty' in the setter. 'SetProperty' is important because it initiates the notification mechanism that notifies the UI when one of these properties is changed (or 'set'). This mechanism is called data binding and you can read up on it if you search for 'WPF data binding'. Anyways I hope this sample helps.
... View more
04-30-2020
05:07 PM
|
2
|
1
|
4236
|
|
POST
|
Hi Abel, Microsoft will continue to support VB and so will the SDK so no worries there. Your point about the documentation is correct and we will update the documentation for the 2.6 release this coming summer.
... View more
04-30-2020
01:58 PM
|
0
|
0
|
2235
|
|
POST
|
I replaced your "Geoprocessing.ExecuteToolAsync" line with the following code snippet and had no problems with the progress dialog. It showed and progressed as expected. I would recommend to run the sample without starting Pro from the debugger - the progress dialog is not guarantied to display properly on the UI when in debug mode. List<object> arguments = new List<object>
{
// store the results in the default geodatabase
CoreModule.CurrentProject.DefaultGeodatabasePath,
// name of the feature class
"TestPnt",
// type of geometry
"POINT",
// no template
"",
// no z values
"DISABLED",
// no m values
"DISABLED"
};
await QueuedTask.Run(() =>
{
// spatial reference
arguments.Add(SpatialReferenceBuilder.CreateSpatialReference(3857));
});
IGPResult result = await Geoprocessing.ExecuteToolAsync("CreateFeatureclass_management", Geoprocessing.MakeValueArray(arguments.ToArray()));
... View more
04-30-2020
12:18 PM
|
1
|
3
|
2730
|
|
POST
|
I have two suggestions: 1) In your calling code you have to 'await' the outcome of the function you call, currently you only 'initiate' the DoGp method and the call returns back to the calling method before the function is actually executed.. Change DoGp(info) to 'await DoGp(info)' and make the btnGo_Click an async Sub. Once you 'await' the function you call you will also get the exception from the called function. 2) Since you just started with Pro Add-ins, i would suggest to make the leap to c# instead of using VB. There are all kinds of advantages in using c# over vb.net, for example: VS has much better intellisense support for c#, most add-in samples and all snippets are in c# enabling copy/paste inheritance, this forum supports only a c# syntax highlighter for code snippets, vb is not supported.
... View more
04-27-2020
06:56 AM
|
0
|
2
|
2235
|
|
POST
|
Thanks for pointing this out, I will fix this. - Wolf
... View more
04-24-2020
05:19 PM
|
0
|
1
|
2673
|
|
POST
|
Regarding your question: What is the ESRI way or best way of doing things like this? Put a ProgressBar control on the dockpane? Or have a ProgressDiaglog popup? I guess this depends on the workflow that your add-in implements: if your workflow depends on the layers that you're loading i would recommend to use the ProgressDialog popup - since you have to wait for those layers loading before you do any further work. If you just load those layers for reference and the layers are not required (optional) for further work you can use a WPF ProgressBar on your dockpane. Regarding your question: I see no concrete examples using the standard WPF ProgressBar control on ESRI GitHub, only the ProgressDialog - which is the main reason I am asking the question. The example you are looking for is here: Map-Exploration - Overlay 3D Since you likely update the UI from a background thread (i.e. QueuedTask.Run) make sure that you properly dispatch your progress update to the UI thread as shown here: arcgis-pro-sdk-community-samples/Overlay3DDockpaneViewModel.cs at 6d7d39d6169b59d34be63e415cdd88d561706491 · Esri/arcgis… private void ProgressUpdate(string sText, int iProgressValue, int iProgressMax)
{
if (System.Windows.Application.Current.Dispatcher.CheckAccess())
{
if (_iProgressMax != iProgressMax) MaxProgressValue = iProgressMax;
else if (_iProgressValue != iProgressValue)
{
ProgressValue = iProgressValue;
ProgressText = (iProgressValue == iProgressMax) ? "Done" : $@"{(iProgressValue * 100 / iProgressMax):0}%";
}
if (sText != _previousText) UpdateStatus = sText;
_previousText = sText;
_iProgressValue = iProgressValue;
_iProgressMax = iProgressMax;
}
else
{
ProApp.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
(Action)(() =>
{
if (_iProgressMax != iProgressMax) MaxProgressValue = iProgressMax;
else if (_iProgressValue != iProgressValue)
{
ProgressValue = iProgressValue;
ProgressText = (iProgressValue == iProgressMax) ? "Done" : $@"{(iProgressValue * 100 / iProgressMax):0}%";
}
if (sText != _previousText) UpdateStatus = sText;
_previousText = sText;
_iProgressValue = iProgressValue;
_iProgressMax = iProgressMax;
}));
}
} And finally if you want to show progress in WPF and you don't have proper percentage completion feedback (0-100%) in your load routines you can also use the 'CircularAnimationControl' as shown in step 15 of this example: arcgis-pro-sdk-community-samples/Framework/DockPaneBookmarkAdvanced at f5f9dda18efa173a56d128f3ea64ca34ac3f68a9 · Esri/a…
... View more
04-23-2020
09:47 AM
|
1
|
2
|
4131
|
|
POST
|
I tried your snippet on a SQLServer data and it worked as expected. You can try to look at the error by adding this: createOp.Create(insp.MapMember, insp.ToDictionary(a => a.FieldName, a => a.CurrentValue));
var createResult = createOp.Execute();
if (createResult != true || createOp.IsSucceeded != true)
MessageBox.Show ($@"Create failed: {createOp.ErrorMessage}");
... View more
04-21-2020
09:10 AM
|
0
|
0
|
1897
|
|
POST
|
In short using the Backstage would be what we recommend. You can look at Uma's blog here: https://community.esri.com/groups/arcgis-pro-sdk/blog/2017/10/09/create-custom-project-and-application-settings-using-the-arcgis-pro-sdk or you can look at this YouTube video https://www.google.com/search?q=youtype+arcgis+pro+custom+settings&oq=youtype+arcgis+pro+custom+settings&aqs=chrome..69i57.97865j0j8&sourceid=chrome&ie=UTF-8#kpvalbx=_yhOeXo-1OYj9-gSGqqiIDQ16
... View more
04-20-2020
02:29 PM
|
0
|
1
|
1204
|
|
POST
|
You can create you own state & condition for this. Make the following changes to your config.daml: Add the following before the <modules> tag: <conditions>
<insertCondition id="has_UVR_Condition" caption="Feature Layer with UVR">
<state id="has_UVR_State" />
</insertCondition>
</conditions> set the <insertModule tag's attribute: autoLoad to true: <insertModule id="TestContextMenu_Module" className="Module1" autoLoad="true" Change you button's condition to the new "has_UVR_Condition": <button id="TestContextMenu_LayerContextMenu_Items_Button1"
caption="Show Selected FeatLyr Name"
className="TestContextMenu_Module:OnMenuButtonClick"
loadOnClick="true" keytip="B1"
condition="has_UVR_Condition"
... and finally add this code to Module1.cs: internal Module1()
{
TOCSelectionChangedEvent.Subscribe(CheckRenderer);
}
/// <summary>
/// This method makes sure
/// 1. The Mapview is Active
/// 2. There is exactly one layer selected
/// 3. The selected Layer is a FeatureLayer
/// 4. The feature layer's rendered is a unique value renderer
/// then sets the state for has_UVR_State & condition
/// </summary>
/// <param name="mapViewEventArgs"></param>
private async void CheckRenderer(MapViewEventArgs mapViewEventArgs)
{
if (mapViewEventArgs.MapView == null || (
mapViewEventArgs.MapView.GetSelectedLayers().Count != 1 ||
!(mapViewEventArgs.MapView.GetSelectedLayers()[0] is FeatureLayer)))
{
SetState("has_UVR_State", false);
return;
}
var bFeatLry = mapViewEventArgs.MapView.GetSelectedLayers()[0] as FeatureLayer;
SetState ("has_UVR_State", await QueuedTask.Run (() => bFeatLry.GetRenderer() is CIMUniqueValueRenderer));
}
internal static void SetState(string stateName, bool active)
{
if (FrameworkApplication.State.Contains(stateName) == active) return;
// toggle the state
if (FrameworkApplication.State.Contains(stateName))
{
//deactivates the state
FrameworkApplication.State.Deactivate(stateName);
}
else
{
//activates the state
FrameworkApplication.State.Activate(stateName);
}
}
... View more
04-20-2020
11:01 AM
|
0
|
0
|
1776
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 10-29-2025 10:48 AM | |
| 1 | 05-24-2021 09:04 AM | |
| 1 | 12-03-2020 08:44 AM | |
| 1 | 10-07-2025 07:27 AM | |
| 2 | 12-29-2025 10:03 AM |
| Online Status |
Offline
|
| Date Last Visited |
05-21-2026
01:59 PM
|