In Part 1 of this article series, we talked through some of the bare basics of customizing ArcGIS Pro. We reviewed some of the high traffic areas of configuration, and some of the functionality of the framework provided by Pro. In Part 2, we’re going to dig deeper into the WPF that drives Pro’s Splash Screen, and cover the basics of MVVM design along the way.
To follow along with Part 2, you’ll need a fresh ArcGIS Pro Configuration project. If you are following along from Part 1, you’re good to go already. If not, instructions can be found here.
WPF, especially as utilized by ArcGIS Pro, follows the Model-View-ViewModel design scheme. The essential breakdown of this pattern is that the UI will fall into three distinct pieces.
There are a number of reasons driving the design of this pattern. The primary goal is the separation of roles between a View and a ViewModel. In the Code-Behind days of Windows Forms, code and UI would be interacting within the same file. In MVVM, we separate the two in order to provide better decoupling. One ViewModel can be used to support any number of Views, and the Views need only bind to the parts that they need. This also allows for the code or the UI to change independently of the other. A developer can update the logic in the ViewModel without breaking the View, or a designer can make changes to the UI without needlessly changing code. This decoupling will ultimately lead to a more robust program and more functional UI.
This is not to say that the Code-Behind is no longer useful in WPF. There are situations where controlling a particular part of the UI (say, selection behavior, or a custom event) simply makes more sense to add to the View rather than the ViewModel. This does, strictly speaking, break from MVVM convention, and knowing the where and how to do so can be trickier to figure out. My general rule of thumb is this: if you need to directly reference a component in the UI, consider using the Code-Behind. If it can be solved with a binding, or through .xaml styling, absolutely do not use the Code-Behind.
For example, in SSP’s Productivity, our Work dockpane needs to directly control and access the selection behavior of a listbox. This particular behavior is difficult to pin down in .xaml, not entirely possible in the ViewModel, but can be solved with just a couple lines of code in the Code-Behind.
Splash Screens are a great way for a piece of software to present basic identity and information that might not be necessarily useful to the user. They’ll often include copyright info, a version indicator, or other info about the software. The splash will also give the user some indication that the program is loading up, and may simply be loading or building resources. Take a look at the Splash Screen for SSP Productivity:
This splash was specifically styled to resemble the default ArcGIS Pro splash, with an SSP rider to indicate that our customizations were installed. When active, it displays the current version of ArcGIS Pro, and has an animated bit of text that tells the user something is going on in the background.
We’ll start by building a similarly useful Splash Screen. The customization you have loaded will include a very basic splash already:
Not very exciting, is it? Let’s spruce that up a little bit. Open up your Configuration project.
The first thing we need to do is add a ViewModel for the Splash Screen to reference. Add a new .cs file to your UI folder, and call it something sensible, like SplashScreenViewModel.cs.
Note: Visual Studio will automatically add .UI to the namespace for this file, which I find to be inconvenient for WPF uses. For this demo I removed the extension from all files and set the namespace at the project default. If you do this, be sure to be thorough about removing it. Each item in the UI folder will need it removed, including code-behinds and .xaml references. This is an optional step, but keep it in mind in case issues arise later. A bad namespace can be one of the biggest culprits behind a bad data bind.
Ofttimes your Splash Screens won’t need anything as complex as a ViewModel. Esri’s template for instance just has some bare-bones text. We’re going to use the ViewModel to spice up the splash screen with some basic dynamic information.
If you haven’t already, open SplashScreenViewModel.cs. We’re going to add some basic properties for the View to access. For right now, add a couple public string properties with blank setters and getters. Let’s call them AppName, Author, and AssemblyVersion. Go ahead and add a public constructor while you’re at it, and set some values for AppName and Author.
Here’s a snippet of the constructor:
The last step is to have your ViewModel inherit from PropertyChangedBase, and add the suggested using statement. This is an Esri-provided class that implements most of the things we need from WPF.
The next step is to add some code that tells the view where to get its data from. Open the ConfigurationManager class and locate the OnShowSplashScreen() method. Replace the method with the snippet below (including the private field)
This code serves to set up the view, and point it at an instance of the ViewModel.
Now that we have some basic data to work with, let’s do something with it. Open SplashScreen.xaml. You’ll see a block of markup text that describes the Splash Screen. You can also change the layout of this window to match your layout preferences. The default will show the preview above and the code below; I personally prefer to have preview left and code right.
Let’s take a look at the code. A little more than half of what we see here is header information describing the properties of the window. We can leave most of this alone for now, but take a look over it. Most of the properties are pretty self-explanatory; we see the width and height of the window, definitions for style, startup location, taskbar behavior, xml schemas, etc.
I do want to point out two lines of import. The first is x:Class=”…”, which should be immediately after the window’s beginning tag. This property defines the code behind class for the window. We don’t need this right now, but this is how the app will know which class drives the view.
The second line of note is xmlns:local=”…”. This property defines an alias for the namespace of the project. We can use this alias to set the base data context for the view, in addition to any other references to code or functions we may need.
Here's the code section that defines what our text looks like.
We’re going to make some basic changes to put the information we have into some Textblocks.
Here’s a snip of the final view:
Go ahead and build the project (Shift+Ctrl+B) and click Start (F5). With luck, you should see something similar to the following:
Not bad, but it’s still a little dry. Let’s add some color to the background. <Grid> has a number of properties we can set here. Background=”<system_color>” is one of the easiest ones that comes to mind. I went with Cornflower Blue:
So there we have it. We’ve barely scratched the surface of what WPF is capable of, but we now have a basic understanding of binding and the MVVM structure. In the next article, we’ll talk about some of the ways we can spruce up the backgrounds even more with gradient brushes, and we'll start working on customizing ArcGIS Pro's Start Page.
If you want to learn more about designing with WPF, one of the best ways is to just start tinkering with it. We've used some basic layout techniques, but you can try using the Grid to define more a absolute layout. See if you can load a logo into the splash. Did you know you can nest a view inside of another view? See if you can make another view and embed it into the Splash screen (hint: <local:MyView/>).
You can find a .zip of the final project from this article here.