您的位置:首页 > 产品设计 > UI/UE

Windows Mobile UI 设计

2012-05-21 14:56 260 查看
一、概述:
      Windows Mobile
是基于Windows CE操作系统的,是针对小内存和有限资源的移动设备而进行的开发,因此在开发过程中同PC的开发有很大的区别。特别是UI的开发,要针对手持设备进行开发,同时要符合手持设备的习惯操作。下面就我在开发过程中对UI开发的认识进行一些叙述。

二、Pocket PC UI
设计:(用户界面设计)
1、标准控件的使用:
     Pocket PC 可以使用.Net Compact Framework中的所有控件,有Listview,TreeView,Button,Label等等,支持的所有控件可见Microsoft
Visual Studio .NET 2003中或可查看msdn进行查看。所有控件的用法可查询msdn。下面就InputPanel控件和Panel控件的主要用途进行一些简单的叙述。
     (1)InputPanel控件:
       由于大部分的Pocket PC
设备都是不带键盘的,因些所有的输入全靠SIP(Soft Input Panel)来进行操作。在.Net的程序中只要加Menubar,就会出现SIP的按纽。但是在SIP出现之后就会覆盖屏幕的下面。这样当在SIP的显示的地方有控件或者是有显示内容时就会被覆盖掉,不能进行查看或者说操作。在实际的编程过程中可以采用两种方法来进行:第一种,也是最简单的一种,在设计程序的时候把SIP的位置给空出来;第二种,就是通过在Form中加入InputPane控件,在InputPane的EnableChange事件中处理当InputPanel的状态发生变化时视图所做的变化操作。
如图所示:

      
代码示例:

    private void inpSIP_EnabledChanged(object sender, System.EventArgs e)

         {
              if (inpSIP.Enabled)
              {
                   tabControl.Height = 246 - inpSIP.Bounds.Height;
              }
              else
              {
                   tabControl.Height = 246;
              }
         }

另外还有一种情况就是我不想在Form中增加Inputpanel控件,但在我还想在当我的输入框取得焦点时能够显示SIP,这种情况的解决方法是我们通过P/Invoke技术,调用本地的SIP操作函数SipShowIM()来实现,具体的代码如下:
class Sip

{

     ///<summary>

         /// SIP constants (as defined in SIPAPI.h)
         ///</summary>
         private
const int SIPF_ON = 0x00000001;
         private
const int SIPF_OFF = 0x00000000;
 
         ///<summary>
         /// P/Invoke native Api SipShowIM
         ///</summary>
         ///<param name="dwFlag"></param>
         ///<returns></returns>
         [ DllImport("coredll.dll", EntryPoint="SipShowIM") ]
         private
extern static bool showSIP(int dwFlag);
 
         public
static bool showSIP()
         {
              return showSIP(Sip.SIPF_ON);
         }
 
         public
static bool hideSIP()
         {
              return showSIP(SIPF_OFF);
}

}
     在文件的顶部增加using System.Runtime.InteropServices;
     使用方法为:比如对于TexBox来说,当TextBox取得焦点时,在TextBox控件的GotFocus事件中实现SIP的显示,在LostFocus中实现SIP的隐藏,代码如下:
private void textBox_GotFocus(object sender, System.EventArgs e)
     {
         Sip.showSIP();
     }
     private
void textBox_LostFocus(object sender, System.EventArgs e)
     {
Sip.hideSIP();

}

     (2)Panel控件的应用
     Panel控件是一个容器,它可以包含其它的控件,主要应用有:
     1)我最多的应用就是当在一个Form中可能会有几种显示样式时,我就增加几个Panel,每个Panel中加入其所需的控件,当我需要显示某一样式时通过
     panel1.Visible =
false;
panel2.Visible = true;
来实现。

      2)设置一些不能直接设置背景色的控件的背景色。比如设置Label控件的背景色.把Label控件改入到Panel控件当中,设置Panel的背景色就可以了。
     3)实现Form的滚动,当一个Form要显示很多控件时,就会出现需要滚动显示,对于.Net 2003来说不能实现自动的滚动,这就要借助于Panel来实现。关于本点的实现可以参见
3、Form滚动的实现
 
2、Form中的一些主要实现方式:
    (1)Form最小化和关闭的实现:
      
主要是得用Form属性MinimizeBox来实现,
      
this.MinimizeBox = false; //
关闭
       this.MinimizeBox =
true;  //最小化
    (2)非全屏Form的实现:
新建一个Form,分别设置属性FormBorderStyle,ControlBox等的值如下所示:
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.ControlBox =
false;
this.ClientSize =
new System.Drawing.Size(224, 88);  // 设置Form的大小
然后在Load事件中设置Form显示的位置,如下例(Form居中显示):
private
void Form_Load(object sender, System.EventArgs e)
         {
              Rectangle screen = Screen.PrimaryScreen.Bounds;
              this.Location =
new Point((screen.Width - this.Width) / 2,
                   (screen.Height - this.Height ) / 2);
}
(3)Form的强制最小化实现:
首先重写Form的onGotFocus方法,然后查找窗体的窗口,最后用ShowWindow(hwnd, SW_MINIMIZE)来最小化窗口。
代码示例如下:
using
System.Runtime.InteropServices;
[DllImport("CoreDll")]
public static extern IntPtr FindWindow(string className,string WindowsName);
[DllImport("CoreDll")]
public static extern
bool ShowWindow(IntPtr hwnd,int nCmdShow);
const int SW_MINIMIZE = 6;
protected override void OnGotFocus(EventArgs e)
{
IntPtr hwnd = FindWindow(null, this.Text);
ShowWindow(hwnd, SW_MINIMIZE); 
base.OnGotFocus(e);
}
(4)父窗口与子窗口之间的关系:
在.Net里当一个窗口产生一个子窗口后,如果常时间不操作或者是一小心回到home screen,这时当你再打开程序关闭子窗口时,会返回到home screen,而不是你想要的父窗口,对于这种情况的处理,最好的方法是把父窗口的指针传入到子窗口中,然后在子窗口关闭时,在子窗口的Closing事件中调用父窗口的show方法来显示父窗口,代码示例片段如下:
父窗口:
public class Form1 : System.Windows.Forms.Form
{
……..
private
void menuItem3_Click(object sender, System.EventArgs e)
             {
                   CustomerForm fmCustom =
new CustomerForm(this);
                   fmCustom.ShowDialog();
                   this.textBox1.Focus();  // 这点很重要
}
}
子窗口:
public class CustomerForm : System.Windows.Forms.Form
{
     private Form parentForm;
              public CustomerForm(Form parentForm)
              {
                   InitializeComponent();
 
                   this.parentForm = parentForm;
     }
private
void CustomerForm_Closing(object sender, CancelEventArgs e)
              {
                   parentForm.Show();
     }
}
注:我见意子窗口的产生最后用模态对话框,即ShowDialog,这样可以避免过多的子窗口的产生,造成内存的浪费。另外,对于窗口返回后,指定要接受焦点的控件,并且这点很重要。
3、Form滚动的实现:
由于.Net 的Form不支持自动滚动,因些要实现Form的滚动要借助于Panel来实现。在Form中加入一个Panel控件,加入一个vScrollBar控件,设置vScrollBar1控件的高度为Form的高度或者说你Panel的设度,如果你的滚动范围不是整个Form,设为Panel的高度,反之也可为Form的高度。然后根据需要设置vScrollBar的LargeChange和Maximum属性,通过在vScrollBar的ValueChanged事件中设置Panel的位置来实现滚动。如下所示:
private void vScrollBar_ValueChanged(object sender, System.EventArgs e)
     {
         vScrollBar.Top = -vScrollBar.Value * 44;  // 44为每滚动一次Panel要移动的大小。
}
具体的可参见\\192.168.20.199机器上VSS下的windows mobile\sample中的CustomForm.cs文件,此示例是Smartphone的,但也可用于Pocket PC,对于Smartphone里还有另一种实现方法,见(ScrollForm.cs),稍后将会详细介绍。
4、Pocket PC UI的整体设计:
      
(1)由于mobile的资源有限,因此在UI的设计时,控件不要过多,同是还要保证可以
    
用手操作,且不会出现误操作,比如:button控件不能过小且紧挨等。当某一功能有过多的操作时,可以将一些常用的或者说主要的操作放到首页面上,然后增加一个More或者高级按按钮来显示其它的操作。也可以借助TabControl来进行分类显示。
如下图所示:
    

      
(2)尽量减少输入操作,而增加方便用户操作的选择操作。
      
比如:设置->区域设置如图:
      
 
(3)尽量对控件进行动态的创建。由于现在的Pocket PC
增加了横屏显示,以及高分辨率的出现,这样为了便于程序能够运行在各种各样Pocket PC上,在开发的过程中要尽量的考虑这些因素。这点也是今后开发过程中最需要注意的一点。
 
三、           Smartphone UI
设计:
   
Smartphone的UI设计相对于Pocket PC
来说又有一定的差异,首先Smartphone不支持触笔的操作,增加了键盘操作,并且所有的操作都是通过键盘来完成。这样就限制了Smartphone对一些控件的支持度。在Smartphone的开发中有许多控件不支持,比如:Button,TabControl,Inputpanel等等。所有在Microsoft
Visual Studio .NET 2003的Tools box中显示恢色的控件我们都不能使用,对于一些特定的控件要我们自己来进行开发。
(1)Smartphone MenuBar设计习惯。Smartphone
的MenuBar有两个Item,左键主要是常用操作,并且不支持子菜单,右键为菜单项,可以在其中设置任何菜单操作。另外,我们可以在一个Form中设置多个主菜单,当根据需要时进行切换。切换方式为:
         this.Menu =
this.mainMenu1;  //
mainMenu1为你当前需要的menu。

(2)设置基于 Windows Mobile
的 Smartphone 输入模式:
代码示例如下:

public class Win32Pinvoke
     {
         public
enum InputMode
         {
              Spell = 0,
              T9 = 1,
              Numbers = 2,
              Text = 3
         }
         // Constants required for interop
         const
int GW_CHILD = 5;
         const
uint EM_SETINPUTMODE = 0x00DE;
 
         [DllImport("coredll.dll", EntryPoint="GetCapture")]
         private
static extern IntPtr GetCapture();
         [DllImport("coredll.dll", EntryPoint="GetWindow")]
         private
static extern IntPtr GetWindow(IntPtr hWnd,
int uCmd);
         [DllImport("coredll.dll", EntryPoint="SendMessage")]
         private
static extern uint SendMessage(IntPtr hWnd,
uint msg, uint wParam,

              uint lParam);
 
         public
static void SetInputMode(Control ctrl, InputMode mode)

         {
              // Get the handle for the current control
              ctrl.Capture = true;
              IntPtr h = GetCapture();
              ctrl.Capture = false;
              // Get the child window for the control
              IntPtr hEditbox = GetWindow(h, GW_CHILD);
              // Set the input mode
              SendMessage(hEditbox, EM_SETINPUTMODE, 0, (uint)mode);
         }
}

使用方法如下:

private
void textBox_GotFocus(object sender, System.EventArgs e)
     {
              Win32Pinvoke.SetInputMode(this.textBox,Win32Pinvoke.InputMode.Numbers);
}

(3)Smartphone中控件的Tab顺序:

Smartphone中控件的Tab顺序和加入控件的顺序一致,比如:有件:TextBox1,TextBox2,Textbox3,我们想要Tab顺序为3->2->1,那么我们在Form中加入的顺序就应该为

this.Controls.Add(this.TextBox3);
              this.Controls.Add(this.TextBox2);
         this.Controls.Add(this.TextBox1);

对于VS2003自动生成的代码,我们需要在InitializeComponent()函数中手动更改他们的顺序。

 

(4)Form滚动的实现:

Smartphone的滚动的实现有两种方式:一种是没有接受输入焦点控件的实现,我称其为Label滚动;另一种是有接受输入焦点的控件的实现,我称为TextBox滚动。

1)Label滚动:见(Pocket PC UI
设计第三点Form滚动的实现)这点最主要的一点是焦点要在VScrollBar上,在Form的Load事件中要指定vScrollBar.Focus(),这样就可以响影导航键里上下键的操作。

2) TextBox滚动:同样是利用Panel和VScrollBar来实现,不同的地方就是当每次可接受焦点的控件接受到焦点时,要计算当前Panel的显示位置。

代码示例:

public ScrollForm()
         {
              //
              // Windows 窗体设计器支持所必需的
              //
              InitializeComponent();
 
              //
              // TODO: 在 InitializeComponent
调用后添加任何构造函数代码
              //
              this.vScrollBar1.Height =
this.ClientSize.Height;
              this.vScrollBar1.Minimum = 0;
              this.vScrollBar1.Maximum =
this.panel1.Height - this.ClientSize.Height;
}

///<summary>
         ///设置当前的显示位置.
         ///</summary>
///<param name="topSender">当前接受焦点的控件的顶层控件,比如一个TextBox上的解释性Label控件</param>
         ///<param name="bottomSender">当前接受焦点的控件</param>
         private
void SetScrollPosition(object topSender,
object bottomSender)
         {
              //get bounds of controls to focus on
              int top = ((Control)topSender).Top - 2;
              int bottom = ((Control)bottomSender).Bottom;
              int height = bottom - top;
 
              //get scroll position
              int pos =
this.vScrollBar1.Value;
 
              //check if control is within view
              if (pos < top && bottom < (pos+this.ClientSize.Height))

              {
                   //do nothing
                   return;
              }
 
              //check if control is above view
              if (bottom < pos + height)

              {
                   //scroll up to view, ensuring the topSender is first visible on form
                   this.vScrollBar1.Value = top;
              }
 
              //check if control is below view
              if (bottom > (pos+this.ClientSize.Height))

              {
                   //scroll down to view, ensuring the bottomSender is last visible on form
                   this.vScrollBar1.Value = bottom -
this.ClientSize.Height;
              }
 
              // Set the panel position on the form, to redraw the application
              this.panel1.Top = -this.vScrollBar1.Value;
 
              return;
         }
使用如下:

private
void textBox1_GotFocus(object sender, System.EventArgs e)
         {
              SetScrollPosition(this.label1,sender);
}
(5)Form中的一些主要实现方式:

本节可参见Pocket PC UI
设计中的第二点Form中的一些主要实现方式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息