Version

Responsive Layout On Neighbor Resize

This topic is designed to help you understand the concept of responsive layout when a neighboring layout of the XamDataGrid control is resizing.

Required Background

The following topics are prerequisites to understanding this topic:

Topic Purpose

This topic provides basic steps required for adding the XamDataGrid control to your view and populating it with sample data.

This topic provides information how to implement responsive layout on rotation of the XamDataGrid control.

Introduction

It may be necessary to modify the width of the XamDataGrid control in your application, due to changes in the dimensions of neighboring layout(s); in such a scenario, you should ensure that the data in your application is presented in such a way that allows for legibility as well as maintaining aesthetics. This example will walk you through the process of implementing a responsive layout behavior with the XamDataGrid control to respond to the conditions in this scenario. The sample will use a Button to change the width of the XamDataGrid control, (by modifying the width of a neighboring view); in response, you will apply the ResponsiveState objects to hide low priority columns from view, (Territory and Sales columns) for maintaining readability for critical data, (Name column).

Prepare Application

Before implementing responsive layout behavior, you need to prepare your application projects and save parameters of device’s screen because they will be later used to define ResponsiveState objects of the XamDataGrid control.

  1. In the Portable application project, add this code to define parameters of device’s screen:

In C#:

public partial class App : Application
{
    static public int ScreenWidth;
    static public int ScreenHeight;
    static public float ScreenDensity = 1;
    ...
}
  1. In the .Droid application project, add this code to save parameters of device’s screen:

In C#:

public class MainActivity : FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        App.ScreenDensity = Resources.DisplayMetrics.Density;
        App.ScreenWidth   = Resources.DisplayMetrics.WidthPixels;
        App.ScreenHeight  = Resources.DisplayMetrics.HeightPixels;
        ...
    }
}
  1. In the .iOS application project, add this code to save parameters of device’s screen:

In C#:

public partial class AppDelegate : FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        App.ScreenWidth  = (int)UIScreen.MainScreen.Bounds.Width;
        App.ScreenHeight = (int)UIScreen.MainScreen.Bounds.Height;
        ...
    }
}

Responsive Layout Example

You will need to set up the layouts for the application; this sample uses several nested layouts for controlling and illustrating the XamDataGrid control’s reaction to various width densities by modifying the width of neighbour layouts.

The following diagram illustrates the arrangement of these layouts for clarification:

Responsive Layout On Neighbor Resize 1.png
  1. Add the following code to your main view to create above layouts with one XamDataGrid control that will resize in response to changing size of the LeftGutter when a Button is clicked.

In XAML:

<Grid x:Name="RootLayout" Margin="10"  >
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Button x:Name="Button" Text="Change Grid Size"/>

    <Grid x:Name="ContentLayout" Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Grid x:Name="LeftGutter" Grid.Column="0"
               MinimumWidthRequest="0"
               MinimumHeightRequest="100"
               BackgroundColor="#FFCBCBCB" />

        <ig:XamDataGrid x:Name="DataGrid" Grid.Column="1"
                        AutoGenerateColumns="False">
            <ig:XamDataGrid.ItemsSource>
                <local:SampleSalesTeam />
            </ig:XamDataGrid.ItemsSource>
            <ig:XamDataGrid.Columns>
                <ig:TextColumn PropertyPath="FirstName" />
                <ig:TextColumn PropertyPath="Territory" />
                <ig:NumericColumn PropertyPath="Sales"  />
            </ig:XamDataGrid.Columns>
        </ig:XamDataGrid>
    </Grid>
</Grid>
  1. Create five variables of type int for storing width dimensions of LeftGutter and the DataGrid:

The XamDataGrid control will be responding to changes in its width; these changes in width are the result of the changing width of a neighboring layout. This scenario will toggle between three discrete widths for this neighboring layout as a percentage of the total width of the screen, for this example they will include 0%, 25% and 50%; the XamDataGrid control in response will have its width reduced to the remaining screen widths of 100%, 75% and 40%, respectively for these three states.

The LeftGutterWidth25 and LeftGutterWidth50 variables will be used to calculate and store the value in pixels of 25% and 50% of the maximum width of the screen which is stored using the ContentMaxWidth variable.

The DataGridWidth1 and DataGridWidth2 variables will be used to calculate and store the remaining available screen width that the XamDataGrid control will assume after it is resized, these values are necessary for setting the range values for the ResponsiveStates.

static int ContentMaxWidth = (int)(App.ScreenWidth / App.ScreenDensity);
static int LeftGutterWidth25 = (int)(ContentMaxWidth * .25);
static int LeftGutterWidth50 = (int)(ContentMaxWidth * .50);
static int DataGridWidth1 = ContentMaxWidth - LeftGutterWidth25;
static int DataGridWidth2 = ContentMaxWidth - LeftGutterWidth50;
  1. Add the following code to handle Click event for the button that will toggle through three width values of the XamDataGrid control, (in incremental widths of 100%, 50% and 25%) which are relatively proportional to the total width available on the screen.

In C#:

Button.Clicked += Button_Clicked;
...
private void Button_Clicked(object sender, EventArgs e)
{
    // Condition 1: if LeftGutter has its default width
    // then set its width to LeftGutterStop: 25% of screen width
    if (LeftGutter.Width <= 0)
    {
        LeftGutter.WidthRequest = LeftGutterWidth25;
    }
    // Condition 2: if LeftGutter's width is equal to LeftGutterWidth25
    // then set its width to LeftGutterWidth50: 50% of screen width
    else if (LeftGutter.Width == LeftGutterWidth25)
    {
        LeftGutter.WidthRequest = LeftGutterWidth50;
    }
    // Condition 3: if LeftGutter's width is equal to LeftGutterWidth50
    // then set its width to  default state of 0
    else if (LeftGutter.Width == LeftGutterWidth50)
    {
        LeftGutter.WidthRequest = 0;
    }
}
  1. Add a helper method for creating ResponsivePhase objects as is demonstrated in code below:

In C#:

private ResponsivePhase CreatePhase(string columnName, string propertyName, object value)
{
    var setter = new ColumnPropertySetter()
    {
        ColumnName = columnName,
        PropertyName = propertyName,
        Value = value,
    };
    return new ResponsivePhase().AddColumnPropertySetter(setter);
}
  1. Create the first ResponsiveState which will be used as the default state of the XamDataGrid control, prior to any adjustments to its width.

This responsive state will activate when the XamDataGrid control’s width is within the range of DataGridWidth1 to ContentMaxWidth values and display the Territory and Sales columns.

In C#:

var state1 = new ResponsiveState();
state1.MaximumWidth = ContentMaxWidth;
state1.MinimumWidth = DataGridWidth1 + 1;
state1.AddResponsivePhase(CreatePhase("Territory", "IsHidden", false));
state1.AddResponsivePhase(CreatePhase("Sales", "IsHidden", false));
  1. Create the second ResponsiveState which will be used when the XamDataGrid control is resized to a width range between DataGridWidth1 and DataGridWidth2 and hide the Sales column.

In C#:

var state2 = new ResponsiveState();
state2.MaximumWidth = DataGridWidth1;
state2.MinimumWidth = DataGridWidth2 + 1;
state2.AddResponsivePhase(CreatePhase("Territory", "IsHidden", false));
state2.AddResponsivePhase(CreatePhase("Sales", "IsHidden", true));
  1. Create the third ResponsiveState which will be used when the XamDataGrid control is resized to a width less than DataGridWidth2 and hide both Territory and Sales columns.

In C#:

var state3 = new ResponsiveState();
state3.MaximumWidth = DataGridWidth2;
state3.MinimumWidth = 0;
state3.AddResponsivePhase(CreatePhase("Territory", "IsHidden", true));
state3.AddResponsivePhase(CreatePhase("Sales", "IsHidden", true));
  1. Add all three ResponsiveState objects to the XamDataGrid control as shown in this code snippet:

In C#:

DataGrid.ResponsiveStates.Add(state1);
DataGrid.ResponsiveStates.Add(state2);
DataGrid.ResponsiveStates.Add(state3);
  1. Save and run your application to verify the responsive layout behavior of the XamDataGrid control.

Responsive Layout Preview

The following animated graphic demonstrates how the XamDataGrid control’s layout responses when width of a neighboring layout (LeftGutter) changes three times.

  • Initially, the LeftGutter has zero width and the DataGrid shows all three columns, (Name, Territory, Sales) which represents the first responsive state.

  • Then width of LeftGutter increases to 25% of the screen’s width; this triggers the second responsive state which hides the Sales column.

  • After another width increase, the LeftGutter occupies 50% of the screen’s width and the third responsive state triggers hiding of the Territory column.

  • Finally, width of LeftGutter resets back to zero and the first responsive state triggers to show again both Territory and Sales columns.

Responsive Layout On Neighbor Resize 2.gif

Responsive Layout Animations

You can also apply animations to the grid to show smooth transitions between responsive states. For example, applying fade out animation for column hiding operation in the data grid:

In XAML:

<ig:XamDataGrid x:Name="DataGrid" ColumnHidingAnimationMode="FadeOut">
...
</ig:XamDataGrid>

In C#:

DataGrid.ColumnHidingAnimationMode = ColumnHidingAnimationMode.FadeOut;

This animated graphic shows how the XamDataGrid control’s layout responses with addition of animating column hide operation.

Responsive Layout On Neighbor Resize 3.gif

Related Content

The following table lists topics that are related to this topic:

Topic Purpose

This topic provides information how to implement responsive layout on rotation of the XamDataGrid control.

This topic provides information on applying with animations while performing operations on columns and rows of the XamDataGrid control.

This topic provides information on supported column types in the XamDataGrid control.

This topic provides code examples on working with columns in the XamDataGrid control.