首页 > 编程语言 >C#文件列表

C#文件列表

时间:2024-08-17 15:48:53浏览次数:12  
标签:文件 ToolStripMenuItem 控件 C# tsmi 列表 ToString Click oneItem

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),就可以了。

标签:文件,ToolStripMenuItem,控件,C#,tsmi,列表,ToString,Click,oneItem
From: https://www.cnblogs.com/dbsdb/p/18364510

相关文章

  • C240817C. 团队协作:二分答案+贪心
    C240817C.团队协作二分显然,但是被check难住了。以为只能把运动员按速度分成两类,然后二分图找最大匹配,但显然做不动。然后考场上就被卡住了………看了题解突然勾起了对一道题远古的记忆:总之也是二分之后是要看能不能全匹配上。然后当时用的就是sort之后贪心,发现这个贪心很对,......
  • C240817D. 模拟赛:树上dp(以i为起点)+set操作
    C240817D.模拟赛比较显然的树上dp,但是维护set比较烦考场上其实自己是定义\(f[i]\)是以\(i\)结尾,然后这样的话单次更新根本做不到\(O(logN)\).反应实在是太迟钝了,考场想“如果有一种只更新一条链的dp就好了”结果完全没想到只需变成以\(i\)开头就行了.积累经验吧。......
  • C:使用strncpy, memcpy 拷贝字符
    下面是一段C语言的代码片段。介绍如何使用strncpy,memcpy操作字符,字符串。 voidprintData(char*data,intlen,char*comment){if(comment){printf("==========printData:%s==========\n",comment);}for(inti=0;i<len;++i){if......
  • 【C++】STL 知识总复习
    文章目录1.STL使用1.1常见的容器1.1.1序列式容器1.1.2关联式容器1.1.3容器适配器1.2迭代器1.2.1输入迭代器(InputIterator)1.2.2输出迭代器(OutputIterator)1.2.3前向迭代器(ForwardIterator)1.2.4双向迭代器(BidirectionalIterator)1.2.5随机访问迭......
  • 008、Vue3+TypeScript基础,数组和对象的响应式修改方法
    01、App.vue代码如下:<template><divclass="app"><h1>好好学习,天天向上</h1><Person/></div></template><script>//JS或TSimportPersonfrom'./view/Person.vue'exportdefault{//......
  • @clickhouse/client-web部署后出现ClickHose query error:crypto.randomUUID is not a
    crypto.randomUUID报错我这里是因为使用使用@clickhouse/client-web组件,在服务器部署后在浏览器访问界面导致的crypto.randomUUIDisnotafunction报错如果你用http://localhost:端口,在服务器浏览器上访问这个部署的页面,发现不会报错,这是因为,你使用localhost访问......
  • 基于ssm角色访问控制的文件共享系统-附源码161821
    摘要近些年,一些较大的企业经常自行开发科技角色访问控制的文件共享系统,这样做有一定的好处,如成本低廉,上级单位一次开发,基层单位可以重复利用,而且一定程度上能满足个性化需求。但是实践证明,这种开放方式一般难以成功。一方面企业内部开发人员往往生而缺乏项目经验,导......
  • 易优cms目录名称与系统内置冲突,去掉限制方法详解!
    第一步,屏蔽检测文件文件位置:\application\admin\controller\Arctype.php找到代码病注释掉 if(!empty($post['dirname'])&&!$this->arctypeLogic->dirname_unique($post['dirname'],$post['id'])){$arctype_is_......
  • Datawhale X 魔搭 AI夏令营 AIGC方向 Task3
    ComfyUI简介ComfyUI是一个基于节点工作流稳定扩散算法的图形界面,它通过将稳定扩散的流程巧妙分解成各个节点,成功实现了工作流的精准定制和可靠复现。基本概念节点工作流:ComfyUI的核心是基于节点式的工作流程,这种设计允许用户将复杂的稳定扩散过程分解为多个可独立操作的节点,通......
  • 题解:AT_arc181_b [ARC181B] Annoying String Problem
    思路首先我们可以根据两个字符串算出另外一个字符串\(T\)的长度。算出来之后,因为我们要满足等式两边完全相等,所以很容易得出这两个字符串应该都是由一些公共的字串拼接而成的。设\(S\)串中最小的周期为\(P\)。所以应该满足\(|P|\Large{\mid}\normalsize\gcd(|S|,|T|)\)......