[英]Enumerate folder/subfolder contents to right-click context menu of system tray application in C#
我正在使用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资源管理器外壳,实际上必须走的很远,以便将所需文件夹的内容动态枚举到系统任务栏的右键单击上下文菜单中图标?
我对使用.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);
}
}
}
}
}
这是我使用一个简单的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);
}
}
我还没有测试过,但是我认为这或多或少会达到您想要的效果
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.