Layout design tips for Mashups

In this post I’ll give some basic layout tips on how to create your Mashups so that they are resizable, clean and easy to use. A few set of rules will make your Mashups look great. I share a few different layouts that you can use as a starting point for your own development. The minimum requirement for Smart Office is 1024*768 and the recommended resolution is 1280*1024. If you develop a Mashup you probably need to target 1280*1024 just because a composite application requires a high resolution because you want all the different pieces to fit together.

All samples in this post can be downloaded from my SkyDrive. If you have a specific layout that you are struggling with please comment on the post and I’ll try and add it to the samples.

Let’s start with a quick check list:

  • Use margins. A good starting point is to use consistent margins in the range of 4,8,12 and 16.
  • Use margins to set distance to previous control. The margin property sets the margin on all sides of the control, “left,top,right,bottom”. I usually work with the left and top, like this: “8,8,0,0”
  • Use consistent margins, think symmetry, think groups and aligned.
  • Check all your margins and that controls are grouped correctly. Be consistent.
  • Use a tool like an on screen pixel ruler to check margins and alignment
  • Check that buttons have correct margin and correct style. One button should be a primary button and the rest should be secondary.
  • Check that the controls have a sufficient length and try and make all the controls of the same length. If Max-length is used make sure it is correct.
  • Resize your window and check the behavior of the controls. Aim to have a liquid layout that stretches.
  • Write a lot of text in input controls and make sure they don’t resize.
  • Check keyboard navigation

The most important aspect is how you group content and use alignment and margins.

Creating the main panel

Before you can start with adding the controls to your Mashup you need to have your design of the Mashup on a piece of paper. Draw boxes for lists and detail areas and add buttons. If you plan to use tabs think about how to group them and place them relative to the other content. Start with a grid. Decide how many columns and rows you want, if you want a grid splitter so that you can resize the size or the columns or rows. Start by creating the first grid, but don’t feel forced to put everything in rows or columns in that grid directly. You can group content in new grids or stack panels that you place in the first grid as well. I usually work with Grids and StackPanels.

For the layout to be resizable think about using the width and height property, use auto for columns with for example labels, but you should mostly use star -sized columns. This way the UI will stretch. Never place a List or DataGrid in a row that has height set to Auto. The List will think it has all the height it needs and you will never get scroll. The same is true for StackPanels, don’t use StackPanels for lists. Stackpanels are great when you want to add a few buttons in a group.

Below is one example of a master list with three detail areas placed in tabs. I have added a grid splitter so that it is possible to resize the list. Notice that a grid splitter will only work between star sized columns or rows.

Another common layout is to add another column to the right. The second column can be of fixed width if it is a MIPanel that you create yourself, but in my example I used a start sized column. Notice that I added a header to the list just to align the line from the group box with the upper line of the list.

Using tabs is useful when you have limited space. When I browsed deployed Mashups on our development server I found a bunch of Mashups with a menu system to the left. In fact this is the TabControl with TabStripPlacement=”Left”. However I found that the implementation of this mode has a lot of margin. So I did something in the example file that is not something I recommend, I used a negative margin. In general you should never ever use negative margins but in this case I feel that the control template for the TabStripPlacement=Left is not implemented correctly so I needed to compensate for it. Note that this might be considered as a bug and might be fixed in coming versions of Smart Office.

The result looks pretty good. I also added a header that is bound to the current name of the tab.

Here is the code:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI">
	<Grid.Resources>
	</Grid.Resources>

	<Grid.ColumnDefinitions>
		<ColumnDefinition Width="*" />
	</Grid.ColumnDefinitions>
	<Grid.RowDefinitions>
		<RowDefinition Height="Auto" />
		<RowDefinition Height="*" />
		<RowDefinition Height="Auto" />
	</Grid.RowDefinitions>
	<Button Margin="0,8,8,0" Content="About" HorizontalAlignment="Right" />
	<!--Adjust the margin depending on the max length of the tab-->
	<Label Style="{DynamicResource styleGroupBoxHeader}" VerticalAlignment="Bottom" Margin="124,0,0,-8" Content="{Binding SelectedItem.Header, ElementName=TabControl}" />
	<TabControl Name="TabControl" Grid.Row="1" SelectedIndex="0" TabStripPlacement="Left">
		<TabItem Header="Customer Data" Margin="0,0, 0,0">
		  <Border BorderThickness="1" Margin="0,-18,8,8" CornerRadius="4" BorderBrush="Gray">
		    <Grid>
		      <TextBlock TextWrapping="Wrap" Text="Place you content here, if you just have one control you can remove the grid. You can remove the border as well. Specifically if you will show a list. Easiest is to set the BorderThickness to 0." />
		    </Grid>
		  </Border>
		</TabItem>
		<TabItem Header="Orders">
		  <Border BorderThickness="1" Margin="0,-18,8,8" CornerRadius="4" BorderBrush="Gray">
		    <Grid>
		      <TextBlock TextWrapping="Wrap" Text="Place you content here. Use the grid if you need more columns/rows." />
		    </Grid>
		  </Border>
		</TabItem>
		<TabItem Header="Invoice entry">
		 <Border BorderThickness="1" Margin="0,-18,8,8" CornerRadius="4" BorderBrush="Gray">
		    <Grid>
		      <TextBlock TextWrapping="Wrap" Text="Place you content here. Use the grid if you need more columns/rows." />
		    </Grid>
		  </Border>
		</TabItem>
		<TabItem Header="Address">
		</TabItem>
	</TabControl>
	<ui:StatusBar Name="StatusBar" Grid.Row="2" Grid.Column="0" />
</Grid>

How to add a scrollbar

Different areas in the UI might require a scroll if there is not enough space. There are two main approaches, to place scroll viewers inside the areas where you require a scroll or just add a Scroll Viewer at the top of your Mashup. I would recommend placing the entire Mashup content within a Grid. The grid that contains the content should have a MinWidth and MinHeight set. It will look like this:

Always try and resize your window to test how the controls behave. Don’t set fixed sizes. Use a ScrollViewer around the entire Mashup if some of the users are on small screens.

I would always set the scrollbars to have auto visibility.

Here is what the content will look like:

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
  <!-- Content grid with scroll. Notice the MinHeight and MinWidth-->
  <Grid MinHeight="600" MinWidth="800">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
   <Grid.RowDefinitions>
     <RowDefinition Height="*" />
   </Grid.RowDefinitions>
     <TextBlock Text="Content grid with scroll and Status bar always visible" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" FontSize="18" />
   </Grid>
</ScrollViewer>

Consider other options instead of the Group Box in order to group content. Having a header and enough margin will work best in many cases.

Download the Mashup ExampleLayout project. Unzip and open the project file in the Mashup Designer.

For more input read Windows User Experience Interaction Guidelines.

11 thoughts on “Layout design tips for Mashups

  1. Elly

    How do you know which panel to choose from the M3 applications ?
    (detailpanel, listpanel, MiPanel, Micombobox,MiListpanel) when you want to add information from different panels ?
    For example a mash up that would include 4 parts,
    from top left to top right : pps200/A –> PPS200/address change after input of A screen.
    and bottom left to bottom right : PPS201 –> ATS101 attrib change after input of order line.
    How do I know which type of panel to use for PPS200/A, PPS201, etc . ?
    Thank you
    BR, Elly

    1. norpe

      For M3 list panels (such as B-panels) you would use the ListPanel Mashup control. For M3 detail panels (such as E-panels) you would use the DetailPanel Mashup control. The MI-panels can be used to show lists and details using data from MI program transactions. The MI-panels should only be used if there is no standard M3 panel with the required data or if you need to update data from a Mashup.

      You cannot use A-panels in a Mashup. You should use bookmarks to start the programs on the correct panel (B, E etc).

      More information can be found from the Help menu in the Mashup Designer or in the Mashup Designer User guide.

  2. Elly

    Ok, thanks for your answer. I will try it like that. Unfortunately it seems the purchase programs are not represented much in the bookmarks though.
    BR,
    Elly

  3. Pingback: Building a Mashup UI – Margins and alignment explained | Developing for Infor Smart Office

  4. Ted Chong

    Hi,
    Thank you for you tips on how to handle mashup. I am pretty new to Mashup, I only do a couple basic mashups so far. I have a formatting issue that cannot figure out. When I do a mashup on PPS200, and click the filter options. It show one filter Facility: and has two drop down box to pick the range. Everything works. But there is a large white space under that line and the whole filter option occupied half the screen.
    May I know how we can handle this? The Mashup created and deployed and working. Any help will be greatly appreciated.
    Ted.

    1. karinpb Post author

      You mean the filter options section. There is nothing you can do if there is a lot of waste space. Does it look like that in the normal program? It should look like the normal program. We have done some adjustments and collapsed unused white space for some of the programs. So it would depend on the Smart Office version but even more so on the M3 version. PPS200 looks fine for me know but I’m on M3 13.4 and Smart Office 10.2.1 .

  5. Karadok

    HI,
    Thanks for your tips. i would like know how work m3detail panel advanced layout.
    I would like define the number of row, but i don’t find how, cna you help me?

    Best regards.

    1. karinpb Post author

      Hi,
      Here is a general description of the grid layout model: http://www.wpf-tutorial.com/panels/grid-rows-and-columns/.
      Here is an example of a custom detail panel

      <m3:DetailPanel Grid.Row="2" Header="Header Test" EnableScrolling="True" Name="customerDetail" LayoutMode="Advanced">
      		<m3:DetailPanel.Bookmark>
      			<m3:Bookmark Program="CRS610" Table="OCUSMA" KeyNames="OKCONO,OKCUNO" Panel="E" PanelSequence="EF" />
      		</m3:DetailPanel.Bookmark>
      		<m3:DetailPanel.Events>
      			<mashup:Events>
      				<mashup:Event SourceName="customerList" SourceEventName="CurrentItemChanged" />
      			</mashup:Events>
      		</m3:DetailPanel.Events>
      		<m3:DetailPanel.Links>
      			<mashup:Links>
      				<mashup:Link Uri="http://www.google.com/search?q={STAT}" Text="Status Search" />
      			</mashup:Links>
      		</m3:DetailPanel.Links>
      		<Grid Margin="8">
      			<Grid.ColumnDefinitions>
      				<ColumnDefinition Width="Auto" />
      				<ColumnDefinition Width="*" />
      			</Grid.ColumnDefinitions>
      			<Grid.RowDefinitions>
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="30" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      				<RowDefinition Height="Auto" />
      			</Grid.RowDefinitions>
      			<m3:LabelPresenter FieldName="WWCUNO" Grid.Column="0" Grid.Row="1" />
      			<m3:FieldPresenter FieldName="WWCUNO" Grid.Column="1" Grid.Row="1" />
      			<m3:LabelPresenter FieldName="WRCUNM" Grid.Column="0" Grid.Row="2" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRCUNM" Grid.Column="1" Grid.Row="2" Margin="0,5,0,0" />
      			<m3:LabelPresenter FieldName="WRSTAT" Grid.Column="0" Grid.Row="3" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRSTAT" Grid.Column="1" Grid.Row="3" Margin="0,5,0,0" Positions="12" />
      			<m3:LabelPresenter FieldName="WRCUTP" Grid.Column="0" Grid.Row="4" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRCUTP" Grid.Column="1" Grid.Row="4" Margin="0,5,0,0" Positions="12" />
      			<m3:LabelPresenter FieldName="WRPHNO" Grid.Column="0" Grid.Row="5" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRPHNO" Grid.Column="1" Grid.Row="5" Margin="0,5,0,0" />
      			<m3:LabelPresenter FieldName="WRCSCD" Grid.Column="0" Grid.Row="6" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRCSCD" Grid.Column="1" Grid.Row="6" Margin="0,5,0,0" Positions="3" />
      		<!-- WRSDST,WRSMCD,WRRESP, -->
      			<m3:LabelPresenter FieldName="WRSDST" Grid.Column="0" Grid.Row="8" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRSDST" Grid.Column="1" Grid.Row="8" Margin="0,5,0,0" />
      			<m3:LabelPresenter FieldName="WRSMCD" Grid.Column="0" Grid.Row="9" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRSMCD" Grid.Column="1" Grid.Row="9" Margin="0,5,0,0" />
      			<m3:LabelPresenter FieldName="WRRESP" Grid.Column="0" Grid.Row="10" Margin="0,5,0,0" />
      			<m3:FieldPresenter FieldName="WRRESP" Grid.Column="1" Grid.Row="10" Margin="0,5,0,0" />
      		</Grid>
      	</m3:DetailPanel>
      

Comments are closed.