|
POST
|
I got my original code to work by changing the ICommand declaration to this: public ICommand CmdRemoveFromList
{
get
{
return new RelayCommand((SelectedAPNs) =>
{
// Remove items only when SelectedItem isn't null
if (SelectedAPN != null)
{
// Iterate selected items in APN List
foreach (var item in SelectedAPNs as IList<object>)
{
// Get item as a string
string _APN = item.ToString();
// Remove the APN from the ListParcels variable
ListParcels.Remove(_APN);
}
//Clear the dialog APN list
APNsList.Clear();
// Iterate the APNs in the ListParcels variable
foreach (string ListParcel in ListParcels)
{
// Add the APNs to the dialog list
APNsList.Add(ListParcel);
}
}
}, () => true);
}
} I used the CommandParameter in the RelayCommand declaration, added the as IList<object> to type cast the CommandParameter as an iterable IList of objects in the foreach loop and added }, () => true); at the end of the RelayCommand to provide a return value for the RelayCommand. I verified it worked regardless of whether or not the SelectedItems were visible within the current scroll position of the Listbox. So this is the final solution for the xaml, which is nearly identical to the standard MVVM declarations of a Listbox and Button used in Pro, except that I have added a CommandParameter before the button Command. <ListBox x:Name="lbxAPNList" HorizontalAlignment="Left" Height="143" Margin="10,93,0,0" VerticalAlignment="Top" Width="136" SelectionMode="Extended" ItemsSource="{Binding APNsList}" SelectedItem="{Binding SelectedAPN}"/>
<Button x:Name="btnRemoveFromList" Content="Remove from List" CommandParameter="{Binding ElementName=lbxAPNList, Path=SelectedItems}" Command="{Binding Path=CmdRemoveFromList}"/> And this is the final code for the ViewModel, which uses the standard MVVM code for the Listbox source and SelecedItem and only makes slight variations in the standard MVVM ICommand declaration for the button. private ObservableCollection<string> _apnsList = new ObservableCollection<string>();
public ObservableCollection<string> APNsList
{
get { return _apnsList; }
set
{
SetProperty(ref _apnsList, value, () => APNsList);
}
}
private string _selectedAPN;
public string SelectedAPN
{
get { return _selectedAPN; }
set
{
SetProperty(ref _selectedAPN, value, () => SelectedAPN);
}
}
// ListParcels is populated by another button and matches the listbox
// It ensures the list is alphabetically sorted and all values are unique
public static SortedSet<string> ListParcels { get; set; }
public ICommand CmdRemoveFromList
{
get
{
return new RelayCommand((SelectedAPNs) =>
{
// Remove items only when SelectedItem isn't null
if (SelectedAPN != null)
{
// Iterate selected items in APN List
foreach (var item in SelectedAPNs as IList<object>)
{
// Get item as a string
string _APN = item.ToString();
// Remove the APN from the ListParcels variable
ListParcels.Remove(_APN);
}
//Clear the dialog APN list
APNsList.Clear();
// Iterate the APNs in the ListParcels variable
foreach (string ListParcel in ListParcels)
{
// Add the APNs to the dialog list
APNsList.Add(ListParcel);
}
}
}, () => true);
}
}
... View more
09-07-2022
05:22 PM
|
0
|
0
|
9970
|
|
POST
|
I have a ListBox in my ProWindow which is configured for Extended selection so that the user can select multiple items. I also have a button which is supposed to remove the selected items from the list. I set up the binding for the ListBox as an ObservableCollection. If the Selection mode for the Listbox was Single I would set up a binding for the SelectedItem property of the Listbox. However, when the selection mode is set up for Extended selection I want to use the SelectedItems property, not the SelectedItem property. But I am not sure how to set up the binding in my ViewModel so I can get the IList from the SelectedItems property, which is a read only property. (I don't need to set the SelectedItems, I only need to get it) I have read that there is a way to pass the SelectedItems property of the ListBox to a Command using a CommandParameters property. It says that the CommandParameter should be declared before the Command binding. The button xaml code is supposed to look something like this: <ListBox x:Name="lbxAPNList" HorizontalAlignment="Left" Height="143" Margin="10,93,0,0" VerticalAlignment="Top" Width="136" SelectionMode="Extended" ItemsSource="{Binding APNsList}" SelectedItem="{Binding SelectedAPN}"/>
<Button x:Name="btnRemoveFromList" Content="Remove from List" CommandParameter="{Binding ElementName=lbxAPNList, Path=SelectedItems}" Command="{Binding Path=CmdRemoveFromList}"/> However, I am not sure how to set the ViewModel ICommand declaration up so that I can use that command parameter. I tried the following but it doesn't work, since the code is never triggered: private ObservableCollection<string> _apnsList = new ObservableCollection<string>();
public ObservableCollection<string> APNsList
{
get { return _apnsList; }
set
{
SetProperty(ref _apnsList, value, () => APNsList);
}
}
private string _selectedAPN;
public string SelectedAPN
{
get { return _selectedAPN; }
set
{
SetProperty(ref _selectedAPN, value, () => SelectedAPN);
}
}
// ListParcels is populated by another button and matches the listbox
public static SortedSet<string> ListParcels { get; set; }
public ICommand CmdRemoveFromList(IList<object> SelectedItems)
{
get
{
return new RelayCommand(() =>
{
Message = "";
// Iterate selected items in APN List
foreach (var item in SelectedItems)
{
// Get item as a string
string _APN = item.ToString();
// Remove the APN from the ListParcels SortedList
ListParcels.Remove(_APN);
}
//Clear the dialog APN list
APNsList.Clear();
// Iterate the APNs in the module ListParcels variable
foreach (string ListParcel in ListParcels)
{
// Add the APNs to the dialog list
APNsList.Add(ListParcel);
}
});
}
} Is there a way to get the SelectedItems property of a ListBox for use by a button ICommand declaration that works with the Pro SDK?
... View more
09-07-2022
02:25 PM
|
0
|
4
|
9998
|
|
POST
|
Also, the BindingContext is set up properly in my xaml file since my bindings and code are working property and giving change notifications from my textboxes, buttons and listboxes in response to the get and set code of the properties I set up for them. Only the radiobuttons and checkboxes bindings and notifications are not working. However, you are right that I copy/pasted properties that were set to private and didn't notice it. Changing it to public solved the issue.
... View more
09-06-2022
05:04 PM
|
0
|
0
|
1924
|
|
POST
|
I am having trouble understanding how to implement RadioButons and CheckBoxes using MVVM. It seems that Binding the IsChecked property to a bool get/set ViewModel property doesn't work. What is the trick? Here is my xaml set up for the radio buttons: <StackPanel x:Name="StpMatchType" HorizontalAlignment="Left" Height="65" Margin="19,114,0,0" VerticalAlignment="Top" Width="134">
<RadioButton x:Name="rbStart" GroupName="Test" Content="Start of Name" Height="20" IsChecked="{Binding Path=RBStart,Mode=TwoWay}"/>
<RadioButton x:Name="rbAnyPart" GroupName="Test" Content="Any Part of Name" Height="20" IsChecked="{Binding Path=RBAny,Mode=TwoWay}"/>
<RadioButton x:Name="rbExact" GroupName="Test" Content="Exact Name" Height="20" IsChecked="{Binding Path=RBExact,Mode=TwoWay}"/>
</StackPanel>
<CheckBox x:Name="CbxTitle" Content="Set Map Title" HorizontalAlignment="Left" Margin="19,203,0,0" VerticalAlignment="Top" Height="15" Width="90" IsChecked="{Binding SetTitle}"/>
And here are the ViewModel property set up, but this code is never triggered at set up or when I click on one of the radiobuttons: private bool _rbStart = true;
private bool RBStart
{
get { return _rbStart; }
set
{
_rbStart = value;
NotifyPropertyChanged(() => RBStart);
}
}
private bool _rbAny = false;
private bool RBAny
{
get { return _rbAny; }
set
{
_rbAny = value;
NotifyPropertyChanged(() => RBAny);
}
}
private bool _rbExact = false;
private bool RBExact
{
get { return _rbExact; }
set
{
_rbExact = value;
NotifyPropertyChanged(() => RBExact);
}
}
public bool SetTitle
{
get { return Module1.SetTitle; }
set
{
Module1.SetTitle = value;
NotifyPropertyChanged(() => SetTitle);
}
}
//Module1 Code
private static bool _setTitle;
public static bool SetTitle
{
get { return _setTitle; }
set
{
_setTitle = value;
}
}
It seems like all of the Google examples are overly complex and solving value conversion problems that don't apply to me. Even my code seems like overkill, since the behavior of the set of radiobuttons and checkboxes works fine while it ignores my code. I don't want to modify the default behavior of the radiobuttons or checkboxes at all and I don't really have to be notified or do anything when the user actually changes the radiobutton selection or checkbox state. I just need to be able to access the bool state of these buttons in my ViewModel when I trigger some of my other methods. If I can do that without actually needing to bind any of the radiobuttons or checkboxes, that would be great.
... View more
09-06-2022
04:32 PM
|
0
|
3
|
1970
|
|
POST
|
I have adapted my code to generally follow the the example you provided and was able to get the buttons to close the ProWindow the way I wanted. However, I am not sure I have adapted the code in a way that is fully consistent with keeping the Model separate from the ViewModel. In the example provided the Show button class generated with the ProWindow class seems to have been used as the Model class for the MVVM interactions with the map and/or data. However, I am not using the Show button class created for the ProWindow to launch it. Instead I am using a class that sets up the map with layers that support multiple ProWindow options and launch the appropriate ProWindows based on the choice the user makes in a combobox. That class already has extensive code and I don't want to expand it with the code that the example used in the Show button class. But I am willing to create a new class or call the Show button class to handle the Model portion of the MVVM approach for each ProWindow, if that is recommended. The Cancel button that just closes the ProWindow is fine and fully consistent with the purpose of the ViewModel since it does not interact with the map or any data. The other button, called the Locate button, currently is working the way I want it to work, but it is performing map and data operations in the ViewModel that may be better handled in a separate Model class according to MVVM. I would appreciate comments on which portions of this code should be moved from the ViewModel into a separate Model class to make it more consistent with the approach recommended for MVVM. Here is the code: public ICommand CmdLocate => new RelayCommand(async (proWindow) =>
{
String layerName = "Search PLUS Cases";
var ActMap = MapView.Active;
var fLayer = ActMap.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name.Equals(layerName));
if (fLayer != null)
{
if (PLUSCase != null && PLUSCase != "")
{
string whereClause = "CASE_ID = '" + PLUSCase.Replace("'", "''") + "'";
var iCount = await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
// Set up Definition Query filter for the layer
Module1.SetLayerDefinition(fLayer, whereClause, "PLUS Cases");
// Count the filtered features in the layer
var cnt = 0;
using (var cursor = fLayer.Search())
{
while (cursor.MoveNext())
cnt++;
};
if (cnt > 0)
{
// Pause Drawing
ActMap.DrawingPaused = true;
// Clear all selected features in the map
ActMap.Map.SetSelection(null);
// Select the filtered features
fLayer.Select();
// Zoom to Selection
ActMap.ZoomToSelected();
// Reset the camera zoom to zoom out slightly
MapView mapView = ActMap;
// Get the camera for the Active MapView
Camera camera = mapView.Camera;
// Increase the scale by 40%.
camera.Scale *= 1.4;
// Zoom to the camera scale
mapView.ZoomToAsync(camera, TimeSpan.Zero);
//Make the layer visible
fLayer.SetVisibility(true);
// Resure Drawing
ActMap.DrawingPaused = false;
}
else
{
//Make the layer invisible
fLayer.SetVisibility(false);
}
return cnt;
});
// If no selected features
if (iCount == 0)
{
// Show message that No Case Match was found
Message = "No Match Found!";
}
else
// If there are selected features
{
// TODO: set dialog result and close the window
(proWindow as ProWindow).DialogResult = true;
(proWindow as ProWindow).Close();
}
}
}
}, () => true);
... View more
09-06-2022
08:49 AM
|
0
|
0
|
1765
|
|
BLOG
|
The code works in Python 2.7 32 bit, which ArcMap uses, and in Python 3.X 64 bit which ArcGIS Pro uses. The ArcGIS Pro Python requires that you maintain an active connection to ArcGIS Online through ArcGIS Pro to work, so whether or not you normally use ArcGIS Pro you have to periodically open it to maintain the AGOL connection for Python. The Python version you use makes no difference in how you code the dictionary Data Transfer portion of the script. You do have to enclose in parenthesis the outputs of all the print statements in Python 3.X to avoid an error. The advantage of using Python 3.X for this code is that it supports access to more than 2 GB of RAM and is much less likely to fail due to an out of memory error when you work with very large datasets.
... View more
09-03-2022
01:59 PM
|
0
|
0
|
10140
|
|
POST
|
I have a ProWindow dialog that has two buttons. One Button needs to just close the ProWindow and the other button needs to attempt to do an action and if it is successful it needs to close the ProWindow. I would use this.Close() if my buttons were implemented directly in the xaml class of the ProWindow, but I want to use MVVM and want to bind these buttons to the ViewModel and ICommand and RelayCommand. How do I set up the binding so that the button code within the ViewModel class will be able to close the ProWindow?.
... View more
09-01-2022
06:14 PM
|
0
|
2
|
1840
|
|
POST
|
I am using ArcGIS Pro 2.9.3 and have applied a rule package to a building footprint layer with almost 1 million footprint features using a modified version of the Standard Building cga in the Complete Streets example. I am trying to improve refresh performance and am looking for suggestions. I am not satisfied with the options I have tried so far. Prior versions of Pro gave Excessive Refresh Requests errors if I moved the camera in the scene before waiting for each refresh to complete using this layer. Fortunately Pro 2.9.3 seems to have fixed this behavior which at least allows the layer to complete the final refresh when I get the camera where I want it, but refresh performance is still slower than I like once I get to that point. The only suggestion I have seen in the Pro help is to limit the layer scale that will draw in the scene. I have limited the layer scale to 2 miles, which is probably the ideal scale limit for my needs. It works better than having no scale restriction, but it still takes a long time (3 to 5 minutes) for the rule to refresh whenever I pan to an area that forces the cache to reset. Even if I change the scale restriction to a significantly smaller value the refresh performance does not improve very much, and the level of improvement is not worth the limitation of what can be viewed in the scene. It seems that most of the refresh time is still being used to evaluate the vast set of features that ultimately are not displayed. I have 3D Analyst and considered converting the buildings into multipatch features, which does improve performance. If I exclude textures and colors when I build multipatches for the buildings the fgdb file is almost 2 GB, which is a reasonable size. However, I want the rule textures in the final symbology and I don't know of any way to apply the rule textures after generating multipatches it I didn't include the textures through the conversion tool. Unfortunately, if I include textures and colors when I generate multipatches the output file would be between 300 to 400 GB (I cancelled the tool when the file grew to 55 GB after about 15% of progress). That is too large to be justified. I haven't tried this option, but applying a definition query on the layer to limit the extent displayed by the layer using fields with an attribute index, like fields containing centroid coordinate values or community names, should improve performance. However, most of my users wouldn't know how to adjust the definition query when they moved beyond the initial query limits. I could setup separate scenes in advance that limit the amount the user can move, but I don't think my users would know which scene they needed to open to view a particular area given the large number of communities my jurisdiction covers. Setting up tiled layers could be done and placed in a scene, but I would think that performance would only be improved if the layers knew how to turn their visibility on or off in response to the camera position. It is unlikely my users could manually manage to adjust the layer visibility settings any better than they could manage separate pre-made scene files. I don't think there would be any improvement over using the original feature class if the user eventually ends up setting all of the tiled layers to being visible all the time. Is there something I am overlooking? I know how to program and am learning the Pro SDK, so a custom solution is possible. But I was hoping that applying some out of the box techniques would make going that route unnecessary.
... View more
08-04-2022
06:39 PM
|
0
|
0
|
760
|
|
IDEA
|
I voted for your idea and would have a use for this. Please also vote for my idea, which gives other examples of how it would be useful to be able to use Arcade for some of the parameters of other tools. Allow Arcade Expressions in Parameters of Geoprocessing Tools
... View more
07-27-2022
04:33 AM
|
0
|
0
|
4997
|
|
IDEA
|
One of the improvements introduced in ArcGIS Pro is the ability to use Arcade expressions not only as a replacement language where ArcMap used languages like Python or VB Script, such as Labels and Display Expressions, but in new places where ArcMap does not support custom expressions as inputs, such as the Symbology tab. In ArcMap, the Symbology tab only takes existing fields as valid inputs for the unique value category symbology options or the quantities symbology options, which does not allow the user to apply reclassified values or unit conversions to the values in a field without calculating over the values or adding and calculating a new field. However, in ArcGIS Pro the user can use an Arcade Expression instead of a field that can eliminate the need to create or calculate any field in the source data to accomplish symbology effects that present the data under classifications or in units of measure that are not directly stored in the source attributes. However, while applying an Arcade expression to the Symbology tab gives the appearance that the features have merged and dissolved together based on the user defined custom field values, the underlying features have not actually dissolved according to that Arcade expression and cannot be used in a geoprocessing workflow that needs an actual Dissolved feature class that is based on the case values the user custom defined using Arcade. To create the actual Dissolve feature class in ArcGIS Pro the user still needs to add a new field to the source data and calculate the values to be stored in the table prior to running the Dissolve tool. This becomes a real problem when the user has to make a copy of the source data in order to make changes to the schema and the source features class is very large and is only updated on a relatively small percentage of its features each day. The geoprocessing steps required simply to copy the source data, add the field and calculate its values are extremely time consuming and can take up the bulk of the time required to rerun many geoprocessing models if the user is trying to maintain outputs that approach anything resembling real time concurrency with the underlying large data sources. However, if I was able to use an Arcade Expression for the Summary fields or Case field in the geoprocessing tools that do aggregation, like the Dissolve tool, Summary Statistics tool, Frequency tool or Spatial Join tool, I could accomplish the same thing that an Arcade expression now can accomplish in the Symbology tab, but actually output a feature class rather than just the artificial appearance of that dissolve in a map that is only accessible in my project and not suited for further geoprocessing analysis. If Arcade was incorporated into those tools to extend the options available in the parameters that currently only accept fields as inputs, I would be able to eliminate all of the geoprocessing steps currently required to copy the source data and add fields calculated with custom field values to achieve the desired reclassified geoprocessing output. Although not all geoprocessing tool parameters may be suitable to be extended to allow Arcade expressions as alternatives to the standard validated parameter types and the introduction of Arcade into geoprocessing tools presents new challenges for validating the tool parameters, the value of the time saved by users would more than justify the effort in many cases, like the aggregation tools I mentioned. I am sure that many temporary files currently required to carry out most geoprocessing workflows could be eliminated if Arcade was introduced as an option for at least some of the existing geoprocessing tool parameters. Additionally, incorporating Arcade expressions as an option directly implemented for at least some of the geoprocessing parameters would make Arcade even more more portable and reusable across the platform and support the creation of a much larger array of outputs that not only can be used within ArcGIS Pro application itself, but can be used to create outputs that could be exported in formats that are suitable for external use in such things as Traffic Models.
... View more
07-15-2022
09:58 AM
|
7
|
3
|
2370
|
|
POST
|
The Search Forms layouts would have to undergo a huge redesign to fit in a single dockpane. A Button and combobox in the Quick Access Toolbar is working out great. The button launches the chosen search option as a modal ProWindow which has control over the application until the user either cancels the search dialog to close it or choses a valid feature or list of features and presses the Locate button, which closes the dialog and displays the features on the map. The forms do not cover valuable screen area when they are not explicitly requested by the user. My users are very familiar with how my forms behave in ArcMap and want the same experience in ArcGIS Pro. I also do not see a benefit of keeping the form available in a dockpane and having to monitor everything the user might do in the project that would force the search in progress to reset itself. The user is unlikely to know what would trigger a reset and do it without realizing why the search interface reset itself. In fact I don't know all of the possible things a user could do that should trigger a reset and don't want to try to imagine what they are or have to debug them all. While some of the forms are tall and narrow and would easily work in a dockable window, other forms have to be quite wide to be useful. I do not think redesigning those dialogs to fit in a single dockable window is really an option. I also don't want to have to control the width of the dockable window or worry that the user might resize it in a way that would make the form unusable. Anyway, here are the form designs I am trying to port which may give you a better idea of why I think using separate ProWindows is the best design. So far, all indications are that I can make that design work now that only one ProWindow is open at a time and I am no longer calling a ProWindow from within another ProWindow.
... View more
07-08-2022
09:02 PM
|
0
|
0
|
2400
|
|
POST
|
I made sure my code was fully consistent with the code you used and it worked when I launched the form directly. However, I think the issue arose due to the fact that I originally was launching the search case ProWindow from another ProWindow where the user chooses a search to launch from several search options using radio buttons. That was my original design for my ArcObjects Add-In using Windows Forms. The initial Form also did some map set up validation steps through the Search button prior to launching a given search form. However, I suspect that approach is creating too many complications in ArcGIS Pro, so I probably need to rethink the search selection part of the add-in. Would you recommend that I replace the initial ProWindow shown above with a toolbar that contains a dropdown menu of the search choices and a button that launches the appropriate ProWindow based on the kind of search chosen through the dropdown?
... View more
07-07-2022
11:10 AM
|
0
|
0
|
2421
|
|
POST
|
I am trying to run a query on a FeatureLayer in the Active Map through a button in a ProWindow, but either the code throws a Thread Exception if I try to perform a Search on the Layer outside of an async/await block or it skips over the code inside the await portion. Here is the code I have and I have tried it with and without the async/await code: private async void Locate_Click(object sender, RoutedEventArgs e)
{
String layerName = "Search PLUS Cases";
var fLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name.Equals(layerName));
if (fLayer != null)
{
if (this.TbxPLUSCase.Text != null && this.TbxPLUSCase.Text != "")
{
Dictionary<long, string> RoadDict = new Dictionary<long, string>();
string whereClause = "CASE_ID = '" + this.TbxPLUSCase.Text.ToUpper() + "'";
QueryFilter qf = new QueryFilter();
qf.WhereClause = whereClause;
await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
using (ArcGIS.Core.Data.Table PLUSTable = fLayer.GetTable())
{
using (RowCursor rowCursor = PLUSTable.Search(qf))
{
while (rowCursor.MoveNext())
{
using (ArcGIS.Core.Data.Row row = rowCursor.Current)
{
string dictvalue = row["CASE_ID"].ToString();
long v = Convert.ToInt64(row["objectid"].ToString());
RoadDict[v] = dictvalue;
};
}
}
}
});
}
}
this.Close();
}
... View more
07-06-2022
05:38 PM
|
0
|
5
|
2461
|
|
POST
|
Thanks. That is what I was looking for. Is this in the Documentation somewhere? Even if it is, I like having fundamental coding techniques like this posted in the community, since Google does a much better jobs of listing posts in response to searches than it does pages from the SDK documentation.
... View more
07-06-2022
11:59 AM
|
0
|
1
|
3563
|
|
POST
|
I am in the process of converting an Add-In from VB ArcObjects to an ArcGIS Pro Add-In written in C#. The original Add-In was designed using Windows Forms as modal Dialogs. The documentation for the Event Model and Properties of Windows Forms was easy to understand and implement for the adding and using controls on the form. The ProWindow UI template appears to be the closest equivalent to a Windows Form for the ArcGIS Pro Add-In. I have created a project with a ProWindow and added WPF controls that replicate my original Windows Form dialog, but I I don't know anything about what to do after that. The Microsoft documentation examples for WPF are causing errors and I don't understand how to connect the dots. For example, how do I add a button to a ProWindow and handle the button Click event to open a MessageBox saying the button was clicked as the stub code that I can eventually replace.
... View more
07-06-2022
11:17 AM
|
0
|
3
|
3576
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-24-2026 08:01 PM | |
| 6 | 02-23-2026 08:34 AM | |
| 1 | 03-31-2025 03:25 PM | |
| 1 | 03-28-2025 06:54 PM | |
| 1 | 03-16-2025 09:49 PM |
| Online Status |
Offline
|
| Date Last Visited |
03-24-2026
07:54 PM
|