PowerApps Best Practices
In this article we will look at:
- Creating Responsive Screens.
- Using Collections to standardize your UI.
- Other UI Design best practices, including using SharePoint list to configure label text.
- Delegation how to work with it and around it
To demonstrate how you might set up your PowerApp UI to be responsive and standard across the board we will work through some basic examples of principles you can apply throughout your PowerApps design.
We will start with a blank canvas PowerApp in tablet mode. Set the name of your first screen to ‘StartScreen’.
Responsive Top Bar
The first thing we want to look at is making the screens look similar, for this example, we are going to use a Rectangle top bar, but the principle can be used throughout your app.
Step 1 – From the ‘Insert’ menu select ‘Icons’ and scroll all the way down to find ‘Rectangle’. Add it to your screen, and size and position it to show a bar across the top of your screen, something like this.
Give it a meaningful name. e.g ‘rectTopbarStartScreen’. (NB: You may follow a different naming convention)
With all the different devices that a PowerApp can be viewed in, a shape like this can end up showing in various different sizes, you might decide to fix the height by selecting the ‘Height’ property, however doing this would mean you have to set this for every screen you create, so let’s look at how we can do that better.
Step 2 – Create a second screen by clicking the ‘…’ menu next to the first screen and clicking ‘Duplicate Screen’.
Give this second screen a meaningful name. e.g. ‘MiddleScreen’ and rename the rectangle on this screen to be ‘rectTopbarMiddleScreen’.
Step 3 – One way you might choose to set these two (or more if you have other screens) so that the elements on the screen are set to look the same, in this case we are dealing with the height, would be to set the screens height to be the same as the first screen, like this:
So, if you change the first screen the other screen will automatically change. Give it a go.
Step 4 – We can also do the same approach with other Properties, let’s try it with Color.
Select the rectangle on the Middle screen and choose the ‘Fill’ property. Set it as shown:
This will now set the Middle screen Top Bar to be the same color as whatever the Start Screen top bar is set to.
Give it a try, change the colour of the Top Bar on the Start screen.
NB: It is worth noting at this point that the more logic we add to make the screens and controls responsive, the more you have to be careful when changing or deleting those controls that refer to the parents.
Other Responsive Controls
Now as the top bar may change size and position for different device views of this screen, you want to ensure any controls on the screen are positioned in relation to the position of your top bar and in relation to the size of the screen.
For this example, we are going to use a Gallery control on the screen.
Step 1 – Add a Gallery control from the ‘Insert’ then ‘Gallery’ menu.
Name it ‘glyStartScreen’ and manually size it to fill up the remainder of the screen below the Top bar. Like this:
So, the issue with this, is that if the Top bar size changes it the Gallery control will stay where it is, so let’s look at how to solve this.
Step 2 – We are going to set the ‘Y’ property of the Gallery to reference our start screen top rectangle, this will mean that the Gallery is positioned in relation to the rectangle. Meaning that if the size and position of the rectangle move, then the Gallery will also move.
To do this, select your Gallery and choose the ‘Y’ property, and enter the following:
This will set the Y position of our Gallery to be the Y position of the rectangle + the height of the rectangle. So, the Gallery will start where the rectangle ends.
Step 3 – We can also do a similar thing with the Width.
We had previously set the Gallery manually to take up the full screen we can see in the designer window, however different devices can show different sizes. So, to make it Full screen we should set the ‘Width’ property of the Gallery to = ‘Parent.Width’.
This means it will always take its width from the Parent screen size.
Responsive Control Height
Now let’s look at controlling the position of controls on the screen in relation to the Top bar, starting with this Gallery control.
Step 1 – At the moment when we move the rectangle at the top of the screen the Gallery control will move with it, however if you move it far enough the Gallery drops off the screen. So, let’s look at how to solve that.
To Solve this, select the ‘Height’ property of your Gallery control and set it as per below:
This will set the height of the Gallery to be equal to the height of the screen minus the height of the Rectangle at the top of the screen.
NB: As soon as you change this height manually on screen of a control, you will lose any formula that was against that property.
Step 2 – Add a label to your top bar and set the text of the label to equal ‘Start Screen’. Name the label ‘lblTopBarStartScreen’ .
Add a button to the bottom of the screen and set the text to ‘Go to next screen’. It will look something like this:
Step 3 – Of course as we have it setup currently this will mean that the Gallery will go down behind the button. So, we need to update our formula with some further conditions.
Select the Gallery control, and select the ‘Height’ property, add the following formula to the end:
This is now setting the height of the gallery to the height of the screen minus the Top Bar Rectangle height and the bottom button height, meaning that with the position setting we did earlier it will display between the two even when the top bar size is changed.
Step 4 – Let’s set our button to move us to the next screen.
Select the button, select the ‘OnSelect’ property, and set it as per below:
This will move us to the Middle screen with a fade transition effect. Run your App and give it a go!
Position of Controls
Now we are going to look at the middle screen.
Step 1 – Add a label to the screen, call it ‘lblHello’, and set the ‘text’ property of the label to be:
This will say hello to the active user. Let’s make set the ‘Fill’ property to Red and the Color; property to white, to make it look like this:
Step 2 – For this example we want to set the label to always be in the middle of the screen. To do this we need to set its X position and its Y.
X = Horizontal Position (e.g. 0 = left hand side of the screen)
Y = Vertical Position (e.g. 0 = Top of the screen)
Set the X Position
We want it in the middle, so select the ‘X’ property and set it as per below:
This is setting the X value to be the width of the Parent screen divided by 2 minus the Width of the Label divided by 2. If we didn’t do that second part then the labels’ left-hand edge would start in the middle, rather than the whole label being in the middle.
Set the Y position
Using a similar approach, we can now set the Y position:
Now we should have a Middle screen with a label in the middle of the screen looking something like this:
Using Collections to standardize your UI.
So far we have covered some great ways to create responsive screens, however as your application grows you may find it confusing which screen and which control is the parent one.
For some of the properties of your controls a better way to do this is to create a collection.
A collection is a list of values or data that we are storing in our App. You can view the collections in your App by selecting the ‘File’ menu and then choosing ‘Collections’, here you can see what collections are already in your App, at the moment there shouldn’t be any.
So, let’s create a collection.
Step 1 – In the left-hand panel select the ‘App’ at the top and choose the ‘OnStart’ property. This property defines what happens when we start the App, and we are going to use it to create our collection. Set it as per the screen shot below:
This is creating a collection called ‘PAColors’ with a ‘MainColor’ Field set to ‘Blue’ and a ‘SecondaryColor’ field set to ‘Red’.
You can run the ‘OnStart’ formula simply by clicking the ‘…’ menu at the side of the ‘Apps’ and clicking ‘> Run OnStart’. A good way to test it works and populates your collection.
Once you run it, if you go and take a look at your collections you will now see this collection has been created, and in this example with 2 colors.
Of course, as your app gets more complicated you may need more colors for the different aspects, or more collections for different settings.
Using the Collection
How do we use the values in the Collection to set the colors in our Application? Well for each of the controls you want to set to be the MainColor, you would set their ‘Fill’ property to:
In this case this will set these controls to be Blue.
Then you would use the same approach to set controls that you want to use the Secondary color, set their ‘Fill’ property to:
This gives a great way to standardize your Applications throughout.
Other UI Design Best Practices
In this section we are going to cover some UI design techniques to give a good look and feel to your PowerApp, as well as allowing configuration of the Label text in your app via a SharePoint list.
Firstly, we will start with a Loading button.
There are many use cases in applications where the user triggers an action on the screen e.g. Clicks a button, and the application has to go away and carry out an action e.g. Connect to, Save, or Load Something. Often when the user does this they are blocked from interacting with the screen, which is good practice to do, however if the user has no other information on what is happening they may think the application has crashed. Therefore, it is good practice to give some form of ‘Working…’ indication in your UI.
Let’s look at a couple of ways to achieve this:
Step 1 – Insert a ‘Button’ control to your middle screen and position it below the red label we have there already.
Set the ‘OnSelect’ property to set a variable:
So that when the button is clicked we set the variable ‘varStart’ to true.
If you want you can add a label to the screen and set the text to equal ‘varStart’. This is a good way to help debug and understand your apps as you build them, you can have a number of labels on your screen showing the status of various elements, these can then be deleted once the build is complete.
Step 2 – From the controls menu insert a ‘Timer’ control to your screen.
Set the ‘Duration’ property to – ‘6000’ – As this is in milliseconds this means it will be a 6 second timer.
Set the ‘Start’ property to – ‘varStart’ – This will mean the time starts when the variable is true, which is when we click the button.
Set the ‘OnTimerEnd’ property to reset the variable back to false:
Set the ‘Reset’ to the opposite of our variable ‘!varStart’ – NB: Notice the use of the ‘!’ NOT operator in order to set it to the opposite of the variable.
Step 3 – Now we want to disable the button whilst the timer is running, so that it can only be clicked once to trigger the 6 second timer.
To do this set the ‘DisplayMode’ property of the button as shown below:
This will set the display mode of the button to edit when the timer is ‘0’ otherwise it will be set to disabled.
Now run the app and give it a go, you should be able to see that the button is disabled whilst the 6 second timer is running. This would be used when the button is triggering something else in the back ground, maybe a connection or data load.
On its own this is not that useful; however we can use the timer to also show some indication of progress to the user which is always good practice when building a user interface.
NB: We can set the ‘Visible’ property of the Timer control to – ‘False’ now that we know it is working.
Step 4 – Add a ‘label’ control under the button to show the progress.
Set the ‘Visible’ property of the label to:
This will show the label when the button is disabled and hide it when the button is enabled.
This label could have a message in it something like ‘Fetching data’ or ‘Connecting…’ giving the user some confidence that something is happening.
We should now have something looking like this, where on clicking the button the label is shown and the button is disabled, and then after 6 seconds the label is not shown, and the button can be clicked again:
Step 4 – There are many ways to improve this further, so let’s take a look at the label and see if we can make it give even more confidence to the user by showing different text as we progress through the 6 second timer.
Select the Label that is below the button and set the ‘Text’ property to something similar to this, you may have your own messages you want to use:
This will mean that as the timer progresses the message will change showing the user that we are getting closer to the end.
Step 5 – You could also add a loading GIF of some sort that would only display when the Button is disabled.
In the example we have used https://loading.io/ to download a loading GIF to use on the screen. You may have another image or GIF you want to use.
To set this up add your image to the PowerApp media library by selecting ‘File’ then ‘Media’ and uploading the image. Make a note of the image name.
Then add an ‘Image’ control to your screen and set the ‘Image’ property of the control the name of your image file, in this example ‘Spinner-1s-200px’.
Position the image where you want it to show on your screen.
Set the ‘Visible’ property of the image control to:
This will mean that the GIF or Image shows at the same time as our progress message label.
Now when we run the App and click the button we will have something that looks like this:
This gives a much better user experience when we are waiting for something to happen in the background after the user has taken an action, in this case clicking a button.
Pop-up Information Box
Now we are going to look at a way of giving the user a pop-up / pop-out information box on the screen. We will set the text on the information box to come from a SharePoint list. This is a great way to make your application configurable in order to easily maintain the text and information shown on your application.
Step 1 – From the ‘Icons’ menu choose an icon that you want to use as a button for the user to click to show this popup box.
Position the icon in the top right-hand corner of the screen on the blue bar, set the color to white.
Step 2 – Again from the ‘Icons’ menu add a ‘Rectangle’ to the screen. This will be the pop-up window. Name it – ‘ infoCallout’
Position and size it to look something like this:
Step 3 – Now we will set the position of the Rectangle.
Set the ‘X’ Property of the rectangle to:
This will set the X property (left hand edge position) of the rectangle to be equal to the width of the main screen, which puts the rectangle off the screen show it will not show when the App is run.
Step 4 – From the ‘Icons’ menu add the ‘Cancel’ Icon to the top right of the Rectangle, this is to be used to close the pop-up / pop-out menu when it appears.
Name it – ‘icnCloseCallout’
Set the ‘X’ property to be:
This will set the X position of the cross to always be on the right-hand side of the call out box, by referencing the X position and width of the rectangle minus its own width.
We should have something like this:
Now we want to make the Rectangle show on the screen when we click the icon at the top left of the visible screen, and then move out again when we click the cancel / cross icon on the rectangle.
Step 5 – Select the icon that you have used in the top right of your visible screen and set the ‘OnSelect’ property as shown below:
Step 6 – Now reset your Rectangle ‘X’ Property to be:
When you click the Icon on the screen the Rectangle will show over the screen. We now need to be able to move it back using the cancel icon we added to the rectangle.
Step 7 – Select the ‘cancel’ icon and set its ‘OnSelect’ property to the same logic as the icon we used to open it:
This will change the variable and therefore change the result of the formula in the ‘X’ property of the rectangle to move it back to outside the visible screen.
Run the App and give it a go!
Configurable Screen Text
So now we have a pop-out box to display information to the user that currently has no information on it, in this section we will look at how to add text onto the pop-out that is configurable via a SharePoint list.
You will need a data source for your configuration data, in this example we are using a SharePoint list with one item in it as shown:
In a real App you could have many entries each with meaningful titles that could be being used to set the text in different places on your application, field labels, information messages, anywhere that you want the text presented on screen to be configurable.
Step 1 – Add this SharePoint list as a data source in your PowerApp. NB: In our example the List is called ‘Configuration’
Step 2 – Add a label control to your Rectangle and set the text color to white and name it ‘lblCalloutText’.
Step 3 – Connect the label to the data source by setting the ‘Text’ property to:
This will set the text of the label to be the description value of the row in the Configuration SharePoint list where the title = ‘InfoText’.
Now the text should be shown in your label. However, it will not currently be moving with the Rectangle when we open and close the pop-out.
Step 4 – Select the label containing the information text, and set the ‘X’ position property to:
This will keep the label on the rectangle when it moves, you can play with that ’30’ figure to get the position to your liking.
Run your App and give it a go!
Using a SharePoint list like this is a fantastic way to allow users to configure how their application shows to the user. You might use this approach to decide what the text is on each item in a menu, the text shown on buttons or the name shown at the top of each screen.
What is delegation in PowerApps? ……. In short, it means that PowerApps will delegate the processing of data and functions on that data to the data source, rather than moving the data to the app for it to be processed locally.
e.g. If I want to retrieve data from a table with 3000 rows, but I only want to show the rows of data where value is equal to a “X”, then PowerApps uses delegation for this. The PowerApp will then only receive the relevant rows and does not need to get all 3000 and then filter it in the PowerApp.
However not all data, functions, or Formulas can be Delegated. You must be careful what functions you try to use particularly when you are dealing with a large data source.
Formulas that can’t be delegated will be processed locally, meaning that all the data will be brought to your PowerApp which could cause performance issues, but also could hit the limits to the number of rows of data that can be brought back in this way. This can cause false results in your filtering of the data. NB: By default, this limit is set to 500, but can be set to a maximum of 2000.
For more details on what can be delegated and what the limits and constraints are take a look at this Microsoft documentation – https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/delegation-overview
So let’s look at an example of how Delegation can cause problems and a way around it.
For this example, we are using a SharePoint list with 300 rows of data in it. (Our example data has 100 with date in 2017, 100 with a date in 2018, and 100 with a date of later than today in 2019)
If you want to recreate this, you will need similar data.
Step 1 – Firstly we are going to set the ‘Data row limit for non-delegable queries’ to 150. To do this select ‘File’ then ‘App Settings’, and ‘Advanced settings’. You can see the value field at the top. Set it to ‘150’.
Step 2 – Then create a new screen in the PowerApp.
Add a ‘Vertical Gallery’ to it to show our rows of data.
Add a ‘label’ next to the Gallery to show how many rows it is showing. So, we are starting with something that looks like this:
Step 2 – Select the ‘Text’ property of the Label and set it to:
This will mean the label will show the text “Count Rows” with the number of rows in the Gallery next to it. Calculated using the ‘CountRows’ function.
Step 3 – Connect the Gallery to the SharePoint dummy list.
Select ‘View’ menu, select ‘Data Sources’ and on the right-hand menu click ‘+ Add data source’.
Choose ‘SharePoint’ and add your dummy SharePoint List as the data source.
Now select the Gallery, select the ‘Items’ property and set it to the name of your list you have just added as a data source e.g. ‘DummyList’.
Once you have done this you will see that the label now shows in how many records are in your dummy list:
Notice how even though there are 300 items in the list, the count is only showing 100 even though we know we have 300. This is due to the lazy loading, so that no data is loaded unnecessarily.
However, if you run your App and scroll down you will notice the number going up as it loads all the records and will then show all 300 so we have all our rows.
Step 4 – Now we are going to filter the gallery using a function that cannot be delegated. We are going to try and use the Date function.
Select the Gallery and choose the ‘Items’ property, and set a filter as you can see below:
You will notice the wavy blue line in our formula which when you hover over gives a delegation warning, that looks something like this.
This warning is reminding you that you may get some invalid results where formulas can’t be delegated, and where the data row limit for non-delegated queries might affect the outcome.
So, run your App and see how many rows this formula returns, it will likely return the correct result of 100 records for our sample data.
However, if we then flip the formula to bring back the records that are less than now, meaning that if it worked we should get the other 200 records, like this:
Now run the App. You will see that because of the delegation issue along with the 150 row limit being hit, we have not got the expected result, in our example it only filtered 50 rows of data. This is because it has only brought back 150 rows of our data of 300 rows and has then applied the filter.
You may get different results depending on your data.
Delegation Work around
This shows you that you have to be careful when using data sources and when using delegated and non-delegated functions against that data source. The results you get can be incorrect and confusing. Let’s have a look at some ways to work around this constraint.
At Source Data
One method to work around this problem in this instance would be to add a field to our source SharePoint list that is a text field with the Year in it. e.g. 2017, 2018, 2019. Then for the filtering you wanted to do use the years field to do it.
E.g. set the ‘Items’ Property as follows:
Now when you run your App, you will see that the correct amount of data is retrieved, in our example that would be 200 rows.
NB: Don’t forget the Gallery will ‘Lazy Load’ sometimes so you will have to scroll down on the screen to get to the full data set.
With a Collection
If your data isn’t too large to cause performance issues e.g in the 10’s of thousands, another good way to avoid the delegation issues would be to create a collection within your PowerApp. You could do this by adding the following code to the ‘OnStart’ property of your App: – ‘ClearCollect(Dummy, DummyList)’
This would create a collection when that App starts up called ‘Dummy’ that has the data from our SharePoint list in it so that we can filter it in PowerApps and get accurate results.
We would then set the ‘Items’ property to filtered values from this collection instead of directly from the data source, thereby avoiding issues with delegation. Try doing the same filtering we did in our examples above but with this collection and you will see that the results are as expected, and we do not hit any delegation issues.
In the simple examples above we can see how delegation can cause issues in your data results within PowerApps, and that you need consider delegation and its’ limitations in your design, particularly when dealing with larger data sets.
If any part of your formula contains functions or operators that are non-delegable, this can cause false results. Watch out for the errors being indicated within your formula with the blue wavy lines, giving a delegation warning message. These errors mean it might not work, however it may be fine if you are dealing with low number of rows. The error is a good reminder to check if delegation is going to cause issue in each instance.
To work around the delegation constraints, although not always something you have in your control, setting your data up with the constraints in mind can help you achieve the functionality and filtering you need on the data in your PowerApps. In our example we used a text field in the data with the year in so that we could use a function that is Delegable, thereby allowing the data processing to be delegated and passed back correctly to the PowerApp.
Another option would be to bring all the data into a collection within your PowerApp and using this as your data source. Whilst this can help solve your delegation problems, you wouldn’t want to do this if the data set is very large, and it would also present considerations when wanting to update the data or if the data needs refreshing in your app.
Just to remind you again take a look at this article on delegation from Microsoft to help you understand it further – https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/delegation-overview