有没有一种方法可以读取F#控制台应用程序中特定行上的文本



我想把某一行的文本放入一个变量中。我能以某种方式使用Console.CursorLeft和Console.CuratorTop吗?程序是否有可能知道光标当前所在的字母?我有一个程序,你可以使用箭头键来突出显示某一行,但它要求你已经知道行上有什么并重复它

到目前为止,这是一个有效的程序,只是为了让你了解我要做什么。

open System
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 1"
Console.BackgroundColor <- ConsoleColor.Black
Console.ForegroundColor <- ConsoleColor.White
printfn "Option 2"
printfn "Option 3"
Console.SetCursorPosition(0, 0)
let mutable exit = false
while not exit do
let mutable key = Console.ReadKey()
if key.Key.Equals(ConsoleKey.UpArrow) then
Console.SetCursorPosition(0, Console.CursorTop - 1)
if key.Key.Equals(ConsoleKey.DownArrow) then
Console.SetCursorPosition(0, Console.CursorTop + 1)
if key.Key.Equals(ConsoleKey.Enter) then
let selected = Console.CursorTop + 1
Console.SetCursorPosition(0, 3)
printfn "You selected %i" (selected)
exit <- true
let mutable test = Console.CursorTop
Console.SetCursorPosition(0, 0)
printfn "Option 1"
printfn "Option 2"
printfn "Option 3"
if test = 0 then
Console.SetCursorPosition(0, 0)
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 1"
if test = 1 then
Console.SetCursorPosition(0, 1)
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 2"
if test = 2 then
Console.SetCursorPosition(0, 2)
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 3"
Console.BackgroundColor <- ConsoleColor.Black
Console.ForegroundColor <- ConsoleColor.White
Console.SetCursorPosition(0, test)
Console.Read() |> ignore

鉴于注释中的澄清,我认为完全没有理由以需要阅读打印到控制台的文本的方式编写应用程序。

如果您这样做,那么您基本上将依赖控制台文本来维护应用程序的状态。换言之,您正在将您的状态保持在有限大小的2D字符数组中!

更好的方法是使用F#类型来表示状态。例如,您可以定义一个记录来保存您的菜单选项、选择和是否进行了选择的标志:

type State = 
{ Options : string list
Selection : int
Completed : bool }

现在您可以定义一个打印状态的函数:

let printMenu menu = 
Console.SetCursorPosition(0, 0)
for i, option in Seq.indexed menu.Options do
if i = menu.Selection then
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "%s" option
Console.BackgroundColor <- ConsoleColor.Black
Console.ForegroundColor <- ConsoleColor.Gray

还有一个功能,当按下一个键时计算一个新的状态:

let handleKey (key:ConsoleKeyInfo) state = 
match key.Key with
| ConsoleKey.UpArrow -> { state with Selection = state.Selection-1 }
| ConsoleKey.DownArrow -> { state with Selection = state.Selection+1 }
| ConsoleKey.Enter -> { state with Completed = true }
| _ -> state

最后,您可以使用菜单选项定义初始状态。我将保留您的while循环,因此这将是一个可变变量:

let mutable state = 
{ Options = ["Option 1"; "Option 2"; "Option 3"] 
Completed = false
Selection = 0 }      

现在主要的应用程序逻辑非常简单。只要在state.Completed为false时保持循环,打印菜单,读取密钥并更新状态:

while not state.Completed do
printMenu state
let key = Console.ReadKey()
state <- handleKey key state
Console.SetCursorPosition(0, 3)
printfn "You selected %i" state.Selection

这种构建应用程序的方式要清晰得多,因为它将状态保持在显式数据类型中,并与操作它的各种功能分离

最新更新