2015-05-29 43 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 –