2009-08-24 10 views

答えて

1

MaskedTextBoxが該当する場合があります。それに失敗した場合は、入力された値が実際に数値であることを確認するOnTextChangeイベントハンドラを持つ通常のTextBoxを使用することをお勧めします。数値以外の文字であれば、必要に応じてメッセージボックスを叩いたり、それらの文字を完全に削除したりすることができます。

NumericUpDownコントロールは、使用が遅いことがありますが、本質的なデータ検証があり、場合によっては非常に便利です。コントロールが頻繁に使用されないコントロールの場合は、それを使用することを検討してください。それ以外の場合は、MaskedTextBoxまたはTextBoxを使用してください。

+0

MaskedTextBoxはモバイルプラットフォーム上に存在しません。 –

+0

私はそれほど疑わしいので、なぜ「失敗する」と付け加えたのですか? –

11

Windows Mobile(または通常のWindowsアプリケーション)で数値(特に非整数)を入力する最も簡単な方法は、ユーザーが入力するテキストボックスを用意し、入力したことを検証することです適切な数。

のWindows Mobileでのこのアプローチの問題は、デフォルトのSIP(ソフト入力パネル別名小さなポップアップキーボード)はこのようになっていることである。実際のWindows Mobileデバイス上で

alt text http://img510.imageshack.us/img510/6210/sipreg.jpg

、SIPこれよりもさらに小さく見えます。そして、キーナイトの上部にある小さな数字キーを正しく叩くのは巨大な痛みです。これで問題があるということです

alt text http://img16.imageshack.us/img16/6128/sipnum.jpg

:あなたは、この目的のために使用することは、あなたが左上隅にある「123」ボタンをクリックすることで取得数字モード、であり、このようになります。 SIPのこのモードを通常のキーボードの代わりに表示させる方法はありません。 SIPを数値モードで表示させるには、Microsoft.WindowsCE.Formsにプロジェクトへの参照を追加し、このコードを "SIPHandler"という名前のクラスとして追加します(名前空間をプロジェクトの名前空間に変更する必要があります) :

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Drawing; 
using Microsoft.WindowsCE.Forms; 

namespace DeviceApplication1 
{ 
    /// <summary> 
    /// Handles showing and hiding of Soft Input Panel (SIP). Better to use these 
    /// methods than having an InputControl on a form. InputControls behave oddly 
    /// if you have multiple forms open. 
    /// </summary> 
    public class SIPHandler 
    { 
     public static void ShowSIP() 
     { 
      SipShowIM(1); 
     } 

     public static void ShowSIPNumeric() 
     { 
      SipShowIM(1); 
      SetKeyboardToNumeric(); 
     } 

     public static void ShowSIPRegular() 
     { 
      SipShowIM(1); 
      SetKeyboardToRegular(); 
     } 

     public static void HideSIP() 
     { 
      SipShowIM(0); 
     } 

     private static void SetKeyboardToRegular() 
     { 
      // Find the SIP window 
      IntPtr hWnd = FindWindow("SipWndClass", null); 
      // Go one level below as the actual SIP window is a child 
      hWnd = GetWindow(hWnd, GW_CHILD); 
      // Obtain its context and get a color sample 
      // The premise here is that the numeric mode is controlled by a virtual button in the top left corner 
      // Whenever the numeric mode is active, the button background will be of COLOR_WINDOW_TEXT 
      IntPtr hDC = GetDC(hWnd); 
      int pixel = GetPixel(hDC, 2, 2); 
      // Notice that we cannot simply compare the color to the system color as the system color is 24 bit (or palette) 
      // and the real color is dithered to 15-16 bits for most devices, so white (0xff, 0xff, 0xff) becomes 
      // almost white (oxf8, 0xfc, 0xf8) 

      // ken's hack: here we only want to simulate the click if the keyboard is in numeric mode, in 
      // which case the back color will be WindowText 
      //int clrText = (SystemColors.Window.R) | (SystemColors.Window.G << 8) | (SystemColors.Window.B << 16); 
      int clrText = (SystemColors.WindowText.R) | (SystemColors.WindowText.G << 8) | (SystemColors.WindowText.B << 16); 

      SetPixel(hDC, 2, 2, clrText); 
      int pixelNew = GetPixel(hDC, 2, 2); 
      // Restore the original pixel 
      SetPixel(hDC, 2, 2, pixel); 

      if (pixel == pixelNew) 
      { 
       // Simulate stylus click 
       Message msg = Message.Create(hWnd, WM_LBUTTONDOWN, new IntPtr(1), new IntPtr(0x00090009)); 
       MessageWindow.SendMessage(ref msg); 
       msg = Message.Create(hWnd, WM_LBUTTONUP, new IntPtr(0), new IntPtr(0x00090009)); 
       MessageWindow.SendMessage(ref msg); 
      } 
      // Free resources 
      ReleaseDC(hWnd, hDC); 
     } 

     private static void SetKeyboardToNumeric() 
     { 
      // Find the SIP window 
      IntPtr hWnd = FindWindow("SipWndClass", null); 
      // Go one level below as the actual SIP window is a child 
      hWnd = GetWindow(hWnd, GW_CHILD); 
      // Obtain its context and get a color sample 
      // The premise here is that the numeric mode is controlled by a virtual button in the top left corner 
      // Whenever the numeric mode is active, the button background will be of COLOR_WINDOW_TEXT 
      IntPtr hDC = GetDC(hWnd); 
      int pixel = GetPixel(hDC, 2, 2); 
      // Notice that we cannot simply compare the color to the system color as the system color is 24 bit (or palette) 
      // and the real color is dithered to 15-16 bits for most devices, so white (0xff, 0xff, 0xff) becomes 
      // almost white (oxf8, 0xfc, 0xf8) 
      int clrText = (SystemColors.Window.R) | (SystemColors.Window.G << 8) | (SystemColors.Window.B << 16); 
      SetPixel(hDC, 2, 2, clrText); 
      int pixelNew = GetPixel(hDC, 2, 2); 
      // Restore the original pixel 
      SetPixel(hDC, 2, 2, pixel); 

      if (pixel == pixelNew) 
      { 
       // Simulate stylus click 
       Message msg = Message.Create(hWnd, WM_LBUTTONDOWN, new IntPtr(1), new IntPtr(0x00090009)); 
       MessageWindow.SendMessage(ref msg); 
       msg = Message.Create(hWnd, WM_LBUTTONUP, new IntPtr(0), new IntPtr(0x00090009)); 
       MessageWindow.SendMessage(ref msg); 
      } 
      // Free resources 
      ReleaseDC(hWnd, hDC); 
     } 

     [DllImport("coredll.dll")] 
     private extern static bool SipShowIM(int dwFlag); 

     [DllImport("coredll.dll")] 
     private extern static IntPtr FindWindow(string wndClass, string caption); 

     [DllImport("coredll.dll")] 
     private extern static IntPtr GetWindow(IntPtr hWnd, int nType); 

     [DllImport("coredll.dll")] 
     private extern static int GetPixel(IntPtr hdc, int nXPos, int nYPos); 

     [DllImport("coredll.dll")] 
     private extern static void SetPixel(IntPtr hdc, int nXPos, int nYPos, int clr); 

     [DllImport("coredll.dll")] 
     private extern static IntPtr GetDC(IntPtr hWnd); 

     [DllImport("coredll.dll")] 
     private extern static void ReleaseDC(IntPtr hWnd, IntPtr hDC); 

     [DllImport("coredll.dll")] 
     private static extern bool SipSetCurrentIM(byte[] clsid); 

     const int WM_LBUTTONDOWN = 0x0201; 
     const int WM_LBUTTONUP = 0x0202; 
     const int GW_CHILD = 5; 

    } 
} 

ごめんなさい。

SIPHandler.ShowSIPNumeric(); 

か、それは通常のキーボードモードで表示されるようにする::

SIPHandler.ShowSIPRegular(); 

そして再びそれを隠すために:

SIPHandler.HideSIP(); 
を数字モードでSIPをポップアップ表示するには、ちょうどこのラインを使用します

このコードの背後にある基本的なやりかたは、左上隅の色を "覗く"ように並べ替えて、SIPがすでに通常のキーボードまたは数値モードになっているかどうかを判断し、角膜SIPが希望のモードになっていることを確認します。

注:これは「借用」されたWebコードですが、どこから取得したのかわかりません。 SOの誰かがこのハックがどこから来たのか分かっているなら、私に知らせてください。私は元の作者に帰すことができます。

を更新

http://www.danielmoth.com/Blog/InputPanelEx.cs

...元とアレックスFeinmanクレジット:まあ、グーグルの2秒後に、私はこのコードの近接ソースがダニエル・モスだったことがわかりました:

http://www.alexfeinman.com/download.asp?doc=IMSwitch.zip

おかげで、みんな!このコードは実際に私を一度涙にしました(私は当時のタマネギをチョッピングしていましたが、それはできませんでした)。

+0

intersting!それに対して+1。 – moster67

+0

@ moster67:これはいつも私のお気に入りのハックです。これは私がこのコードを見つけるまで何年もひどく苦しんでいた問題です。 – MusiGenesis

+0

母、非常に素晴らしいAPI魔法、ありがとう: –

1

この問題に対する別のアプローチは、オプションの第一の層は、番号の範囲をカバーするマルチレベルのContextMenuを使用することであり、第二層は、ユーザーがこのように、特定の値を選択してみましょう:

alt text http://img19.imageshack.us/img19/6329/dropdowns.jpg

事前に完全なメニュー構造(痛みの種類)を作成したり、値の範囲と必要な解像度に応じて動的に構造を読み込んだりすることができます。これは、Windows Mobileデバイス上でさえ数秒間で何百ものメニュー項目で実行できます。

この方法は、金銭的価値を入力する場合にも非常に効果的です。

+0

私の現在のニーズには役に立たないが、それは本当にクールで独創的な解決策である!もし私が複数回投票することができれば、それはカップルになるでしょう。 :) – eidylon

関連する問題