2015-05-29 52 views
0

在我當前的項目是一個圖形數獨遊戲,我創建了一個按鈕板,當你點擊它被標記的按鈕。標記一個按鈕後,您應該可以按下鍵盤上的一個數字,並且應該檢索該數字(0..9)(如果按0,則爲0,如果按數字1則爲1)。F#keyDown如何獲得按鍵

所以我的問題是:我怎樣才能得到用戶按下哪個鍵盤按鍵,如果它是一個數字,然後檢索它,以便我可以把它放在二維數組中,並顯示爲標記按鈕中的文本?

我包含了我的程序的一部分(如果你得到Fsharpx,System.Forms,System.Drawing和其他必要的庫,這很好編譯),這樣你就可以看到我迄今爲止的想法。

namespace Sudoku 
open FSharp.Control.Observable 

module Main = 

    open System.Windows.Forms 
    open System.Drawing 

    let sudokuGame = Array2D.init 9 9 (fun x y -> 0) 

    let form = new Form(Text="Sudoku game", TopMost=true, Width=360, Height=390) 

    let buttonPos text x y = 
     let defaultSize = new Size(30,30) in 
      (new Button(Text=text, Top=x, Left=y, Size=defaultSize, BackColor=Color.Aqua)) :> Control 

    let gameButtons = [|for y in 1..9 do for x in 1..9 -> (buttonPos "0" (x*30) (y*30))|] 

    let changeText pos c = (Array.get (gameButtons) (pos)).Text <- c 

    form.Controls.AddRange gameButtons 

    let rec obsMerger obsList = 
      match obsList with 
      | x1::[] -> x1 
      | x1::xs -> Observable.merge x1 (obsMerger xs) 
      | [] -> failwith "No Observables" 

    let obsList = [for x in 81..(161) -> Observable.map(fun _ -> x) (gameButtons.[x-81].KeyDown)] @ [ for x in 0..80 -> (Observable.map (fun _-> x) ((Array.get(gameButtons)(x)).Click)) ] 

    let playModeObservables = obsMerger obsList 

    let rec playMode observable gameField lastPressed = async{ 

      let! somethingObservable = Async.AwaitObservable(observable) 

      match somethingObservable with 
      | x  when x < 81 && x > -1 -> return! playMode observable gameField x 
      | x  when x > 80 && x < 162 -> changeText lastPressed ((x-80).ToString()) 
               return! playMode observable gameField (x-81) 
      | _       -> failwith "Shoot" 
     } 

    Async.StartImmediate(playMode playModeObservables sudokuGame 0) ; System.Windows.Forms.Application.Run(form) 
+0

使用它們keydown事件:HTTPS://msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown%28v=vs.110%29 .aspx –

+0

我有一個可觀察的監控keyDown事件,我可以很明顯地得到它們,因爲當我按下一個鍵時,我可以更改按鈕中的內容。我遇到的主要問題是,我似乎無法找到(即使在msdn中)如何獲取哪個鍵被按下,以及如何從該鍵確定哪個值由用戶插入。 –

+0

您是否看到鏈接頁面上的C#示例,該代碼很容易轉換爲F# –

回答

0

感謝@johnpalmer誰給我this網站,因爲從this site和@fyodorsoikin(誰指出我正確的方式)的一個例子我能解決的問題。

要獲得密鑰,您需要一個KeyEventHandler,它需要一個函數,當一個密鑰被敲擊時它會調用它。在這個功能中,你可以檢查其他的東西,做你需要做的事情。

例:

let stuffToDoWhenKeyPressed s (e : KeyEventArgs) = 
     match e with 
     | e when e.KeyCode = Keys.D0 -> gameButtons.[0].Text <- "0" 
     | e when e.KeyCode = Keys.D1 -> gameButtons.[0].Text <- "1" 
     | _ -> GUI.Play.gameButtons.[0].Text <- "?" 

gameButtons.[0].KeyDown.AddHandler(new System.Windows.Forms.KeyEventHandler (fun s e -> stuffToDoWhenKeyPressed s e)) 
+0

你可以更容易一些:KeyDown.AddHandler(stuffToDoWhenKeyPressed)和函數stuffToDoWhenKeyPressed可以改變gameButtons。[0] .Text on(s:?> Button).Text ....但是爲什麼只有一個按鈕被處理? –

+0

啊哈謝謝你會試試看! :)我這樣做,因爲我剛剛瞭解它應該如何完成,現在我將嘗試使它適用於所有按鈕。現在唯一的問題是如何使用按鍵的值更新「常規按鈕」中的文本。 –

+1

約如此:http://pastebin.com/aRw7yRaX我認爲對於這樣一個問題是更適合聊天:http://chat.stackoverflow.com/rooms/51909/f –