我正在使用https://alanbondo.wordpress.com/2008/06/22/creating-a-system-tray-app-with-c/中的模板创建一个具有右键单击上下文菜单的系统托盘图标。
我可以让其中一个按钮启动一个资源管理器进程,该进程使用此函数打开目录的根目录
private void MyApps(object sender, EventArgs e)
{
String currentUser = Environment.UserName.ToString();
Process explorer = new Process();
explorer.StartInfo.FileName = "explorer.exe";
explorer.StartInfo.Arguments = @"C:\Users\" + currentUser + @"\desktop\MyApps";
explorer.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
explorer.Start();
}
我宁愿做的是系统托盘图标按钮,当单击时,展开到一个子菜单,其中包含所需目录的内容,该目录本身包含可浏览的子文件夹。想象一下带有嵌套菜单和应用程序的(Windows 8之前的)“开始”菜单;这就是我想模仿的行为。
到目前为止我发现的是人们编写的多个项目来创建自己的自定义Windows资源管理器shell,实际上必须走得那么远才能动态枚举所需文件夹的内容到右键单击上下文菜单中系统托盘图标?
我更喜欢使用.NET应用程序的visual studio表单,但从我读过的内容来看,没有办法在启动时实际“隐藏”表单,所以现在我正在使用C#
任何建议或意见将不胜感激。谢谢!
编辑:这是更新的代码,其中包含使用指定目录的内容递归填充菜单项的建议方法。我现在收到“System.Windows.Forms.MenuItem”不包含DropDownItems定义的错误
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
namespace MyTrayApp
{
public class SysTrayApp : Form
{
[STAThread]
public static void Main()
{
Application.Run(new SysTrayApp());
}
private NotifyIcon trayIcon;
private ContextMenu trayMenu;
public SysTrayApp()
{
trayMenu = new ContextMenu();
trayMenu.MenuItems.Add("Exit", OnExit);
trayMenu.MenuItems.Add("My Applications").Click += new EventHandler(MyApps);
trayIcon = new NotifyIcon();
trayIcon.Text = "MyTrayApp";
trayIcon.Icon = new Icon(SystemIcons.Application, 40, 40);
trayIcon.ContextMenu = trayMenu;
trayIcon.Visible = true;
}
protected override void OnLoad(EventArgs e)
{
Visible = false; // Hide form window.
ShowInTaskbar = false; // Remove from taskbar.
base.OnLoad(e);
}
private void OnExit(object sender, EventArgs e)
{
Application.Exit();
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
trayIcon.Dispose();
}
base.Dispose(isDisposing);
}
private void MyApps(object sender, EventArgs e)
{
String currentUser = Environment.UserName.ToString();
string[] directories = Directory.GetDirectories(@"C:\Users\" + currentUser + @"\desktop\My Applications");
foreach (string dir in directories)
{
string[] subdir = Directory.GetDirectories(dir);
this.trayMenu.MenuItems.Add(dir);
foreach (string sub in subdir)
{
(trayMenu.MenuItems[trayMenu.MenuItems.Count - 1] as MenuItem).DropDownItems.Add(sub);
}
string[] files = Directory.GetFiles(dir);
foreach (string file in files)
{
this.trayMenu.MenuItems.Add(file);
}
}
}
}
}
答案 0 :(得分:0)
这是一个简单的快速测试,使用简单的ContextMenuStrip。它当然应该是递归的,但只是为了让你走上正轨:
string[] directories = Directory.GetDirectories(@"D:\descargas");
foreach (string dir in directories)
{
string[] subdir = Directory.GetDirectories(dir);
this.contextMenuStrip1.Items.Add(dir);
foreach(string sub in subdir)
{
(contextMenuStrip1.Items[contextMenuStrip1.Items.Count-1] as ToolStripMenuItem).DropDownItems.Add(sub);
}
string[] files = Directory.GetFiles(dir);
foreach(string file in files)
{
this.contextMenuStrip1.Items.Add(file);
}
}
修改强>
当您使用ContextMenu并使用提供的代码时,您应该执行以下操作:
private void MyApps(object sender, EventArgs e)
{
String currentUser = Environment.UserName.ToString();
string[] directories = Directory.GetDirectories(@"C:\Users\" + currentUser + @"\desktop\My Applications");
foreach (string dir in directories)
{
string[] subdir = Directory.GetDirectories(dir);
MenuItem mi=new MenuItem(dir);
foreach (string sub in subdir)
{
mi.MenuItems.Add(sub);
}
string[] files = Directory.GetFiles(dir);
foreach (string file in files)
{
mi.MenuItems.Add(file);
}
this.trayMenu.MenuItems.Add(mi);
}
}
我还没有对它进行测试,但我认为这会或多或少地做你想做的事情