Terminal.Gui这个强大的工具包。Terminal.Gui是一个用于.NET平台的跨平台终端UI工具包,它使开发者能够创建功能丰富、交互性强的控制台应用程序。
Terminal.Gui是一个开源项目,它为.NET开发者提供了一套全面的工具,用于构建复杂的终端用户界面。它支持Windows、macOS和Linux等多个平台,使得开发跨平台控制台应用变得简单而高效。
Terminal.Gui适用于多种应用场景,特别是那些需要在终端环境中提供丰富用户界面的场合:
首先,在你的.NET项目中安装Terminal.Gui NuGet包:
C#dotnet add package Terminal.Gui
一个典型的Terminal.Gui应用程序结构如下:
C#using Terminal.Gui;
class Program
{
static void Main(string[] args)
{
Application.Init();
// 创建主窗口
var win = new Window("My App")
{
X = 0,
Y = 1, // 留出空间给顶部菜单
Width = Dim.Fill(),
Height = Dim.Fill()
};
// 添加控件到窗口
Application.Top.Add(win);
Application.Run();
}
}
这个例子展示了如何创建一个简单的任务管理器应用:
C#using Terminal.Gui;
using System.Collections.Generic;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Application.Run<TaskManagerApp>();
}
}
class Task
{
public string Name { get; set; }
public bool IsCompleted { get; set; }
public override string ToString() => IsCompleted ? "[X] " + Name : "[ ] " + Name;
}
class TaskManagerApp : Window
{
private readonly List<Task> tasks = new List<Task>();
private readonly ListView taskListView;
private readonly TextField newTaskField;
public TaskManagerApp()
{
Title = "Task Manager";
// Create task list view
taskListView = new ListView()
{
X = 0,
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill() - 3
};
// Create a label for the new task input
var taskLabel = new Label("Enter New Task:")
{
X = 0,
Y = Pos.Bottom(taskListView),
AutoSize = true
};
// Create new task input field
newTaskField = new TextField("")
{
X = Pos.Right(taskLabel) + 1,
Y = Pos.Bottom(taskListView),
Width = Dim.Fill() - 20 // Simple fixed adjustment for demonstration
};
// Create add button
var addButton = new Button("Add")
{
X = Pos.Right(newTaskField) + 1,
Y = Pos.Top(newTaskField),
Width = 9
};
addButton.Clicked += () =>
{
if (!string.IsNullOrWhiteSpace(newTaskField.Text.ToString()))
{
tasks.Add(new Task { Name = newTaskField.Text.ToString() });
taskListView.SetSource(tasks);
newTaskField.Text = string.Empty;
}
newTaskField.SetFocus(); // Return focus to the input field
};
// Create complete button
var completeButton = new Button("Complete")
{
X = Pos.Center(),
Y = Pos.Bottom(newTaskField) + 1,
Width = 12
};
completeButton.Clicked += () =>
{
if (taskListView.SelectedItem >= 0 && taskListView.SelectedItem < tasks.Count)
{
tasks[taskListView.SelectedItem].IsCompleted = true;
taskListView.SetSource(tasks);
}
};
Add(taskListView, taskLabel, newTaskField, addButton, completeButton);
taskListView.SetSource(tasks);
newTaskField.SetFocus(); // Set initial focus
}
}
}
这个例子展示了如何创建一个基本的文本编辑器:
C#using Terminal.Gui;
using System;
using System.IO;
using System.Collections.Generic;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Application.Init();
var top = Application.Top;
var win = new TextEditorApp();
top.Add(win);
Application.Run();
}
}
class TextEditorApp : Window
{
private TextView textView;
private StatusBar statusBar;
private string currentFilePath;
public TextEditorApp()
{
Title = "Simple Text Editor";
// Create menu
var menu = new MenuBar(new MenuBarItem[] {
new MenuBarItem ("_File", new MenuItem [] {
new MenuItem ("_New", "", () => NewFile()),
new MenuItem ("_Open", "", () => OpenFile()),
new MenuItem ("_Save", "", () => SaveFile()),
new MenuItem ("_Quit", "", () => Application.RequestStop())
}),
});
// Create text view
textView = new TextView()
{
X = 0,
Y = 1,
Width = Dim.Fill(),
Height = Dim.Fill() - 1
};
// Create status bar
statusBar = new StatusBar(new StatusItem[] {
new StatusItem(Key.F2, "~F2~ Open", () => OpenFile()),
new StatusItem(Key.F3, "~F3~ Save", () => SaveFile()),
new StatusItem(Key.F9, "~F9~ Quit", () => Application.RequestStop())
});
Add(menu, textView, statusBar);
}
private void NewFile()
{
textView.Text = "";
currentFilePath = null;
}
private void OpenFile()
{
var dialog = new OpenDialog("Open File", "Open a text file");
Application.Run(dialog);
if (!dialog.Canceled && !string.IsNullOrEmpty(dialog.FilePath.ToString()))
{
currentFilePath = dialog.FilePath.ToString();
textView.Text = File.ReadAllText(currentFilePath);
}
}
private void SaveFile()
{
if (string.IsNullOrEmpty(currentFilePath))
{
var dialog = new SaveDialog("Save File", "Save your text file");
Application.Run(dialog);
if (!dialog.Canceled && !string.IsNullOrEmpty(dialog.FilePath.ToString()))
{
currentFilePath = dialog.FilePath.ToString();
}
else
{
return;
}
}
File.WriteAllText(currentFilePath, textView.Text.ToString());
MessageBox.Query("Save Successful", "File has been saved", "OK");
}
}
}
Terminal.Gui提供了强大的布局系统,允许创建响应终端大小变化的界面:
C#using Terminal.Gui;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
// 初始化应用程序
Application.Init();
// 创建主窗口
var win = new Window("My Application") // 窗口标题为“My Application”
{
X = 0,
Y = 1, // 为将来的菜单预留空间
Width = Dim.Fill(), // 窗口宽度填满屏幕
Height = Dim.Fill() // 窗口高度填满屏幕
};
// 创建一个居中的标签
var responsiveLabel = new Label("Hello World!") // 标签内容为“Hello World!”
{
X = Pos.Center(), // 水平居中
Y = Pos.Center() // 垂直居中
// 不设置 Width,以正确实现居中
};
// 将标签添加到窗口
win.Add(responsiveLabel);
// 将窗口添加到顶层容器中
Application.Top.Add(win);
// 运行应用程序
Application.Run();
}
}
}
你可以通过继承View类来创建自定义控件:
C#using System;
using System.Threading;
using Terminal.Gui;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
// 初始化应用程序
Application.Init();
// 创建主窗口
var win = new Window("Custom Progress Bar")
{
X = 0,
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill()
};
// 创建自定义进度条
var progressBar = new CustomProgressBar()
{
X = Pos.Center(),
Y = Pos.Center(),
Width = 50,
Height = 1
};
win.Add(progressBar);
Application.Top.Add(win);
// 启动一个新线程来更新进度条
new Thread(() =>
{
for (int i = 0; i <= 50; i++)
{
Thread.Sleep(100); // 每100毫秒更新一次
Application.MainLoop.Invoke(() =>
{
progressBar.Value = i;
progressBar.SetNeedsDisplay(); // 标记需要重绘
});
}
}).Start();
// 运行应用程序
Application.Run();
}
}
public class CustomProgressBar : View
{
public int Value { get; set; } = 0;
public CustomProgressBar()
{
CanFocus = false;
}
public override void Redraw(Rect bounds)
{
Driver.SetAttribute(ColorScheme.Focus);
for (int i = 0; i < bounds.Width; i++)
{
Move(i, 0);
Driver.AddRune(i < Value ? '█' : '░');
}
}
}
}
Terminal.Gui支持异步操作,这在处理耗时任务时非常有用:
C#using System;
using System.Threading.Tasks;
using Terminal.Gui;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
// 初始化应用程序
Application.Init();
// 创建主窗口
var win = new Window("Progress Bar")
{
X = 0,
Y = 0,
Width = Dim.Fill(), // 窗口填满整个宽度
Height = Dim.Fill() // 窗口填满整个高度
};
// 将窗口添加到应用程序顶层
Application.Top.Add(win);
// 在应用程序启动时运行异步任务来更新进度条
UpdateProgressBar(win);
// 运行应用程序
Application.Run();
}
// 更新进度条的异步方法
static async void UpdateProgressBar(Window win)
{
// 创建进度条并设定其位置和宽度
var progress = new ProgressBar()
{
X = Pos.Center(), // 水平居中
Y = Pos.Center(), // 垂直居中
Width = Dim.Percent(75) // 进度条宽度占窗口的75%
};
// 将进度条添加到窗口
win.Add(progress);
for (int i = 0; i <= 100; i++)
{
// 确保UI更新在主线程中完成
Application.MainLoop.Invoke(() => {
progress.Fraction = i / 100f; // 更新进度条的进度
});
await Task.Delay(50); // 模拟工作通过延迟50毫秒
}
// 进度完成后从窗口中移除进度条
Application.MainLoop.Invoke(() => {
win.Remove(progress);
});
}
}
}
Terminal.Gui为.NET开发者提供了一个强大的工具,用于创建复杂、交互性强的控制台应用程序。它结合了传统命令行界面的轻量级特性和现代GUI应用的交互性,为各种应用场景提供了理想的解决方案。
无论是构建开发工具、系统管理应用还是创建独特的用户界面,Terminal.Gui都能满足各种需求。通过本文介绍的特性和示例,相信您已经对Terminal.Gui有了深入的了解,并能够开始使用它来创建您自己的强大控制台应用程序。
随着.NET生态系统的不断发展,Terminal.Gui无疑将在控制台应用程序开发中扮演越来越重要的角色。希望本文能够激发您的创意,帮助您在下一个项目中充分利用Terminal.Gui的潜力。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!