Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile

SIP(soft input panel) Overlapping Controls

2.60/5 (7 votes)
2 Jul 2008CPOL 1   317  
How to solve input panel overlapping problem

Introduction

pc_capture1.JPG pc_capture2.JPG pc_capture3.JPG pc_capture4.JPG

This article gives a simple but very effective explanation to overcome the problem when your controls aren't visible when you open the inputpanel. You can notice in the screenshot that all controls are adapted based on the inputpanel and available free space.

Using the Code

Add the class to your project. It is a static class so it can be called from any form. To let this work, you need to add an inputpanel control to each form. If you are using tabpages, then you pass only the current tab page. For example:

C#
OverLappingInputPanel.Inputpanel(tabControl1.TabPages
[tabControl1.SelectedIndex].Controls, inputPanel1.Enabled, 
inputPanel1.VisibleDesktop.Height); 

The OverlappingInputPanel class:

C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;  

namespace MFA_Common
{
    public static class OverLappingInputPanel
    {
        private static int oldrest = 0;
        private static int oldheight = 0;
        private static int oldtop = 0;
        private static Control isFocused = null;

        /// <summary>
        /// Brings the control that has focus on top of the inputpanel
        /// </summary>
        /// <param name=""controls""></param>
        /// <param name=""SIDCollaps""></param>
        public static void Inputpanel(Control.ControlCollection controls,
            Boolean SIDExpended, int Visualdesktopheight)
        {
            try
            {
                if (controls != null)
                {
                    if (SIDExpended == true)
                    {
                            //Loop through the controls to determinate which has focus
                            //this can be avoided if the gotfocus event is fired
                            //for each control that is beneath the inputpanel if expanded

                                foreach (Control ctrl in controls)
                            {
                                if (ctrl.Focused)
                                {
                                    isFocused = ctrl;
                                    // if this is not the case calculate the needed space
                                    int rest = Visualdesktopheight - (
                                        ctrl.Top + ctrl.Height);
                                    if (rest < 0)
                                    {
                                        //move each control up with the calculated space
                                        foreach (Control ctrl2 in controls)
                                        {
                                            ctrl2.Top = ctrl2.Top + rest;
                                        }
                                        oldrest = rest;

                                    }
                                    if (ctrl.Height > Visualdesktopheight)
                                    {
                                        oldtop = ctrl.Top; 
                                        oldheight = ctrl.Height;
                                        ctrl.Height = Visualdesktopheight;
                                        ctrl.Top = 0;
                                    }
                                }
                            }

                            //escape the current function if the selected control is
                            //not under the inputpanel
                            return;
                    }
                    else
                    {
                        //when the inputpanel is hidden, recalculate the top position
                        //for each control.
                        //the old value has to be reversed *-1 to inverse the changes
                        //if the control was bigger than the available screen, then
                        //give it back its original value 
                        if (oldheight != 0)
                        {
                            isFocused.Top = oldtop; 
                            isFocused.Height = oldheight;
                            oldheight = 0;
                        }
                        foreach (Control ctrl2 in controls)
                        {
                            ctrl2.Top = ctrl2.Top + (-1 * oldrest);
                        }
                        oldrest = 0;
                    }
                }
            }

            catch 
            {
                //the ObjectDisposedException is trapped here. This occurs when the user 
                //doesn't closes the sip before moving to an other screen
                //if an inputpanel is closed on an other form, 
                //then the object that is stored is dispose
                //if this is the case, catch the exception and set the object to null;
                oldrest = 0;
                controls = null;
            }
        }
    }
}

The code can be improved if you pass the object that requires the adjustment of the screen. Just add for each control the gotfocus event that is overlapped by the inputpanel and pass it to the function. Then the function doesn't need to loop over each control that is in the control container.

History

  • 2nd July, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)