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?.
Solved! Go to Solution.
Here is a sample that implements a ProWindow using MVVM: Esri/arcgis-pro-sdk-community-samples: ArcGIS Pro SDK for Microsoft .NET Framework Community Samples...
Here is a sample that implements a ProWindow using MVVM: Esri/arcgis-pro-sdk-community-samples: ArcGIS Pro SDK for Microsoft .NET Framework Community Samples...
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);