C#文件列表
窗体页面制作
需要控件Panel,设置属性Dock控制所处的位置。用于在窗体上分组和组织其他控件。
在Pannel里拖入Lable,Button,TextBox,Listview,FolderBrowerDialog,ContexMenuStrip,ImageList等控件。
ListView:可以平铺的布局,用于以多种视图模式(如大图标、小图标、列表、详细信息等)显示数据项列表。
FolderBrowerDialog:文件夹浏览对话框,用于让用户选择一个文件夹。
ContexMenuStrip:上下文菜单条,用于为其他控件提供右键上下文菜单。
ImageList:用于存储一组图像,这些图像可以被其他控件(如ListView,TreeView等)共享和使用。
留白的方式:
-
第一种方式:可以用anchor,拉伸。
-
第二种方法:padding边框到子控件之间的距离。
margin边框到上一级控件的距离。
拖控件的顺序:占满剩余空间的那个,选择最后拖进去的布局控件,这样就不会占用别的布局控件的空间了。想修改顺序的时候,就去修改designer文件里的代码。
嵌套层级比较多的时候,可以选中当前的,然后点击esc键,就可以返回上一级嵌套。
转到定义,designer文件里有详细的设置。designer设计的代码,设置的比较早。在Form里面设置,会比较晚,也可以写在窗体加载函数里。
拖一个控件,它会在designer文件里实例化。可以自己写个类实例一个控件,不用写在designer里面。
字体Font会被继承,字体颜色也可以被继承,背景颜色,会被下一级沿用。
构造函数
public Form1()
{
// 初始化组件,VS帮开发者生成界面布局,开发者向设计器拖放的所有控件都在在FormXXX.Designer.cs文件生成代码。
// InitializeComponent()就是在FormXXX.Designer.cs文件中。
InitializeComponent();
// 手动创建控件
/*Button button = new Button();
button.Size = new System.Drawing.Size(180, 54);
button.Name = "btnByCode";
button.Text = "通过代码创建的按钮";
// button位置
//button.Location = new Point(50, 60);
panel1.Controls.Add(button);*/
// 手动绑定事件
// 完整写法:
//大图标ToolStripMenuItem.Click += new EventHandler(SearchToolStripMenuItem_Click);
// 简写:只要方法能满足委托(方法的形参和返回值,与委托保持一致)。
// 事件不能连等。
/*大图标ToolStripMenuItem.Click += SearchToolStripMenuItem_Click;
小图标ToolStripMenuItem.Click += SearchToolStripMenuItem_Click;
列表ToolStripMenuItem.Click += SearchToolStripMenuItem_Click;
详细信息ToolStripMenuItem.Click += SearchToolStripMenuItem_Click;*/
// 循环绑定事件
var list = 查看ToolStripMenuItem.DropDownItems;
foreach (var item in list)
{
ToolStripMenuItem tsmi = item as ToolStripMenuItem;
tsmi.Click += SearchToolStripMenuItem_Click;
}
var list2 = 排列方式ToolStripMenuItem.DropDownItems;
foreach (var item in list2)
{
if (item is ToolStripSeparator) continue;
ToolStripMenuItem tsmi = item as ToolStripMenuItem;
tsmi.Click += ArrangeModeToolStripMenuItem_Click;
}
}
窗体加载
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "文件列表";
// 窗体加载时,默认加载D盘
LoadFolder(@"D:\");
}
右键菜单-查看
// sender发送者,事件的发送者,你点击了哪个控件,sender就是谁。sender装箱
private void SearchToolStripMenuItem_Click(object sender, EventArgs e)
{
// 1.选中
// 让当前点击的菜单项选中
ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
tsmi.Checked = true;
// 其他的菜单项不选中
var list = 查看ToolStripMenuItem.DropDownItems;
foreach (var item in list)
{
ToolStripMenuItem oneItem = item as ToolStripMenuItem;
if (oneItem.Name == tsmi.Name) continue; // 把当前点击的菜单项跳过。
oneItem.Checked = false;
}
// 2。功能(设置查看模式)
listView1.View = (View)Enum.Parse(typeof(View), tsmi.Name);
/*if (tsmi.Text == "大图标")
{
listView1.View = View.LargeIcon;
}
else if (tsmi.Text == "小图标")
{
listView1.View = View.SmallIcon;
}
else if (tsmi.Text == "列表")
{
listView1.View = View.List;
}
else if (tsmi.Text == "详细信息")
{
listView1.View = View.Details;
}
else if (tsmi.Text == "平铺")
{
listView1.View = View.Tile;
}*/
}
右键菜单-排列方式
private void ArrangeModeToolStripMenuItem_Click(object sender, EventArgs e)
{
// 1.选中
// 当前点击的项
ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
tsmi.Checked = true;
// 分两组,每一组互斥选中
var list = 排列方式ToolStripMenuItem.DropDownItems;
// 循环取每一组中选中的项
ToolStripMenuItem item1 = null; // 保存排列方式
ToolStripMenuItem item2 = null; // 保存升序或降序
foreach (var item in list)
{
// A.实现选中
if (item is ToolStripSeparator) continue; // 中线
ToolStripMenuItem oneItem = item as ToolStripMenuItem;
// tsmi.Tag.ToString()=="1"判断是点击属于哪一组。
// oneItem.Tag.ToString() == "1"判断循环当中的某项属于哪一组。
if (oneItem.Tag.ToString() == "1" && tsmi.Tag.ToString() == "1")
{
if (oneItem.Text != tsmi.Text) oneItem.Checked = false;
}
else if (oneItem.Tag.ToString() == "2" && tsmi.Tag.ToString() == "2")
{
if (oneItem.Text != tsmi.Text) oneItem.Checked = false;
}
// B.实现把每一组选中的项记录下来
if (oneItem.Tag.ToString() == "1")
{
if (!oneItem.Checked) continue;
item1 = oneItem;
}
else if (oneItem.Tag.ToString() == "2")
{
if (!oneItem.Checked) continue;
item2 = oneItem;
}
}
// 2.功能(排列方式,排序)
/*
ToolStripMenuItem item1 = null; // 保存排列方式
ToolStripMenuItem item2 = null; // 保存升序或降序
foreach (var item in list)
{
if (item is ToolStripSeparator) continue; // 中线
ToolStripMenuItem oneItem = item as ToolStripMenuItem;
if (oneItem.Tag.ToString() == "1")
{
if (!oneItem.Checked) continue;
item1 = oneItem;
}
else if (oneItem.Tag.ToString() == "2")
{
if (!oneItem.Checked) continue;
item2 = oneItem;
}
}*/
// 排序,比较:IComparer,有两组比较的条件
// 参数1:按XX比较。参数2:升序或降序
// ListViewItemSorter属性给Sort()设置比较器。
listView1.ListViewItemSorter = new MyListItemSorter(item1.Text, item2.Checked);
listView1.Sort();
}
点击按钮切换目录
private void btnOpen_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.ShowNewFolderButton = false;
//dialog.Description = "fjdlsjfldsjfljdsf";
//dialog.RootFolder=Environment.SpecialFolder.Windows;
DialogResult dialogResult = dialog.ShowDialog();
if (dialogResult == DialogResult.OK)
{
txtPath.Text = dialog.SelectedPath;
LoadFolder(txtPath.Text);
}
}
加载目录方法
// 加载选择的目录下的文件夹及文件(一层)
private void LoadFolder(string path)
{
// 1.先清空原来的列表
listView1.Items.Clear();
// 2.加载文件夹
// 拿到目录实例
DirectoryInfo directoryInfo = new DirectoryInfo(path);
// 拿到目录下的所有的子文夹
DirectoryInfo[] subDirs = directoryInfo.GetDirectories();
for (int i = 0; i < subDirs.Length; i++)
{
DirectoryInfo dir = subDirs[i];
Console.WriteLine(dir.Attributes);
if ((dir.Attributes & FileAttributes.Hidden) > 0) continue; // 排除隐藏文件夹
if ((dir.Attributes & FileAttributes.System) > 0) continue; // 排除系统文件夹
/*string[] arr = dir.Attributes.ToString().Split(new string[] {", "},StringSplitOptions.None);
if (Array.IndexOf(arr, "Hidden") != -1) continue;
if (Array.IndexOf(arr, "System") != -1) continue;*/
// ListViewItem可以又包含子项, ListViewItem能不能填写图片
// ImageIndex图片索引,是ListView1控件关联的ImageList中的图片的序号
ListViewItem listViewItem = new ListViewItem(dir.Name, "shell32_1_4.ico");
//ListViewItem listViewItem = new ListViewItem(dir.Name, 0);
listViewItem.SubItems.Add(dir.LastWriteTime.ToString("yyyy/MM/dd HH:mm"));
listViewItem.SubItems.Add("文件夹");
listViewItem.SubItems.Add("");
// 先把列表中添加的项用ListItem实体保存下来,目的:将来排序用。
ListItem model = new ListItem()
{
Name = dir.Name,
UpdateTime = dir.LastWriteTime,
Type = "文件夹",
Size = 0M
};
listViewItem.Tag = model;
// 给listView1添加一项,项的类型ListViewItem
listView1.Items.Add(listViewItem);
}
// 3.加载文件
// 拿到目录下的所有的文件
FileInfo[] files = directoryInfo.GetFiles();
Array.ForEach(files, file =>
{
ListViewItem listViewItem = new ListViewItem(file.Name, 1);
listViewItem.SubItems.Add(file.LastWriteTime.ToString("yyyy/MM/dd HH:mm"));
listViewItem.SubItems.Add(GetType(file.Extension));
listViewItem.SubItems.Add(Math.Ceiling(file.Length / 1024M).ToString("N0") + " KB");
// 先把列表中添加的项用ListItem实体保存下来,目的:将来排序用。
ListItem model = new ListItem()
{
Name = file.Name,
UpdateTime = file.LastWriteTime,
Type = GetType(file.Extension),
Size = Math.Ceiling(file.Length / 1024M)
};
listViewItem.Tag = model;
listView1.Items.Add(listViewItem);
});
}
// 根据文件扩展名,得到文件类型
private string GetType(string extension)
{
if (extension == ".txt")
{
return "文本文档";
}
else if (extension == ".bat")
{
return "Windows 批处理文件";
}
// ......其他文件类型自行判断
else
{
return "未知";
}
}
LIstItem.cs
namespace FileList.Model
{
public class ListItem
{
public string Name { get; set; }
public DateTime UpdateTime { get; set; }
public string Type { get; set; }
public decimal Size { get; set; }
}
}
Compare.cs
namespace FileList.Compare
{
public class MyListItemSorter : IComparer
{
// 保存排序的列
private string colName = string.Empty;
// 保存升序或降序
private bool asc = false;
public MyListItemSorter(string colName, bool asc) {
this.colName = colName;
this.asc = asc;
}
// x排序前一项,y排序后一项
public int Compare(object x, object y)
{
ListViewItem item1 = (ListViewItem)x;
ListViewItem item2 = (ListViewItem)y;
ListItem model1 = (ListItem)item1.Tag;
ListItem model2 = (ListItem)item2.Tag;
if (colName == "名称")
{
// 按字符串比较
return CompareString(model1.Name, model2.Name, asc);
}
else if (colName == "修改日期") {
return CompareString(model1.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss"), model2.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss"), asc);
}
else if (colName == "类型")
{
return CompareString(model1.Type, model2.Type, asc);
}
else if (colName == "大小")
{
return CompareDecimal(model1.Size, model2.Size, asc);
}
return 0;
}
private int CompareString(string name1, string name2, bool asc)
{
if (asc)
return name1.ToLower().CompareTo(name2.ToLower());
else
return name2.ToLower().CompareTo(name1.ToLower());
}
private int CompareDecimal(decimal size1, decimal size2, bool asc)
{
if (asc)
return (int)(size1 - size2);
else
return (int)(size2 - size1);
}
}
}
在windows平台上,图片不合适,造成和应用程序分辨率不匹配造成的失真问题,模糊,可以通过放开应用程序配置清单app.manifest里的一个注释来解决这个问题。
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
如何添加app.mainfest?
-
方法一:在项目上右键单击,选择属性。在默认打开的选项卡中选择嵌入带默认设置的清单。没有效果。
-
方法二:在项目上右键单击,添加项,选择应用程序配置清单文件(仅限Windows),就可以了。