闲来无事,这几天学习了线程,想在winfom里调用 异步委托来实现。好多需求都没有完成,哎。。。
第一个是:仿资源管理器
问题:如何实现 双击击 listView 打开目录,关键点是:我不会获取 listView选中项目的路径
代码如下:
View Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Runtime.Remoting.Messaging;
using System.Diagnostics;
namespace 资源管理器
{
//声明委托
public delegate void DeleMethod(string[] dirs);
public delegate void DeleMethod2(TreeNode node);
public partial class explorer : Form
{
public explorer()
{
InitializeComponent();
}
TreeNode parent;
private void explorer_Load(object sender, EventArgs e)
{
parent = treeView1.Nodes.Add("我的电脑");
GetDrive(parent);
listView1.LargeImageList = imageList1;
}
/*
*
*
*
* 方法
*
*
*/
//获取磁盘
private void GetDrive(TreeNode parent)
{
string[] drives = Directory.GetLogicalDrives();
foreach (var drive in drives)
{
parent.Nodes.Add(drive);
}
}
//获取某磁盘的目录(文件夹)
private void GetDir(TreeNode oneNode)
{
DeleMethod dele = ListShow;
DeleMethod dele2 = ListViewShow;
DeleMethod2 dele3 = PicShow;
string[] dirs = Directory.GetDirectories(oneNode.Text);
//异步线程1
dele.BeginInvoke(dirs, null, null);
//异步线程2
dele2.BeginInvoke(dirs, null, null);
//异步线程3
dele3.BeginInvoke(oneNode, null, null);
//主线程
foreach (var n in dirs)
{
oneNode.Nodes.Add(n);
}
}
//显示在ListBox
private void ListShow(string[] dirs)
{
listBox1.Items.Add("当前线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
foreach (var n in dirs)
{
listBox1.Items.Add(n);
}
}
//显示在ListView
private void ListViewShow(string[] dirs)
{
foreach (var n in dirs)
{
string name = Path.GetFileName(n);
listView1.Items.Add(name);
}
}
//显示图标
private void PicShow(TreeNode node)
{
for (int i = 0; i < node.Nodes.Count; i++)
{
listView1.Items[i].ImageIndex = 0;
}
}
//打开文件夹
private void OpenDir(string path)
{
Process.Start("explorer.exe", path);
}
/*
*
*
*
* 事件
*
*
*/
//单击Node节点事件
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
listBox1.Items.Clear();
listView1.Items.Clear();
if (e.Node.Parent == null)
{
return;
}
else
{
//改善异常操作对用户的界面体验
try
{
GetDir(e.Node);
}
catch (Exception m)
{
MessageBox.Show("请将磁盘插入驱动器(DVD):", "插入磁盘", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
//实现ListView双击打开目录
private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
MessageBox.Show("********未实现********");
}
//实现ListBox双击打开目录
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (listBox1.SelectedItems.Count != 1)//防止多选,在Load加载listView1.MultiSelect = false;也可以
{
return;
}
else
{
string path = listBox1.SelectedItem.ToString();
string[] temp = Directory.GetFileSystemEntries(path);
listBox1.Items.Clear();
foreach (var n in temp)
{
listBox1.Items.Add(n);
}
}
}
}
}
第二个是:局域网Ping 整个网段的工具
以前写过一个,但是,那个效率。。。实在是。。。这次加入了异步委托,实现了 异步线程执行,效率大大提高了。
代码如下:
View Code
PING局域网存活PC(线程版)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespace WindowsFormsApplication6
{
public delegate string DeleMethod(string ip,int i);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = DateTime.Now.ToLocalTime().ToString();//加载的时候就显示时间
//实时更新
timer1.Enabled = true;
timer1.Interval = 1000;
}
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = DateTime.Now.ToLocalTime().ToString() ;
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
//判断正确的输入格式
if (textBox1.Text == string.Empty || textBox2.Text == string.Empty)
{
MessageBox.Show("IP地址不为空", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
return;
}
else
{
if (textBox2.Text.Length > 3 | textBox2.Text.Length<=0)
{
MessageBox.Show("第二组IP有误", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
return;
}
else if (int.Parse(textBox2.Text) == 255 || int.Parse(textBox2.Text) == 0)
{
MessageBox.Show("第二组IP为广播地址", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
return;
}
else
{
string[] ips = textBox1.Text.Split('.');
if (ips.Length != 4)//因为IP是4段
{
MessageBox.Show("第一组IP有误", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
return;
}
if (int.Parse(ips[3]) == 0 || int.Parse(ips[3]) == 255)
{
MessageBox.Show("第一组IP为广播地址", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
return;
}
int i1=int.Parse(ips[3]);
int i2=int.Parse(textBox2.Text);
if(i1>i2)
{
MessageBox.Show("后面IP太小", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
return;
}
DeleMethod delemethod = Ping;
AsyncCallback callBack = new AsyncCallback(callMethod);
for (int i = i1; i <= i2; i++)
{
delemethod.BeginInvoke(i.ToString(),i,callBack,null);
}
}
}
}
//回调函数
private void callMethod(IAsyncResult ar)
{
AsyncResult result = (AsyncResult)ar;
DeleMethod dele = (DeleMethod)result.AsyncDelegate;
string temp=dele.EndInvoke(ar);
listBox1.Items.Add(temp);
}
private string Ping(string ip,int i)//调用Ping方法
{
string temp;
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";//获取程序的事件 注意FileName包含路径
p.StartInfo.UseShellExecute = false;
//重定向 标准输出 输入 错误
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;//不显示窗口
p.Start();
p.StandardInput.WriteLine(string.Format("ping -n 1 192.168.0.{0}",ip));
p.StandardInput.WriteLine("exit");
temp=p.StandardOutput.ReadToEnd();
if (temp.Contains("Received = 1"))
{
return string.Format("ID:"+Thread.CurrentThread.ManagedThreadId+"\n"+"提示:192.168.0.{0}存在", i);
}
else
{
return string.Format("ID:" + Thread.CurrentThread.ManagedThreadId + "\n" + "提示:192.168.0.{0}可能不存在", i);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult result=MessageBox.Show("是否要关闭软件","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
e.Cancel =false;//这是一个关闭事件,不取消事件,也就是不关闭
}
else
{
e.Cancel = true;//这是一个关闭事件,取消事件,就是关闭
}
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
总结:
1.winform中 调用异步委托 不是我们 想象的那么简单。
2.
问题:大家都知道MessageBoxButtons的枚举值,是显示 确认 取消的,这是一个枚举,但是我今天想找一个 “只显示 取消”按钮的,居然没找到,所有我想增加 枚举值,不知道如何做?
求给思路。
3.
对异步线程的总结:
异步线程:不管你是否使用EndInvoke();在winform中 都不会影响 你的”显示结果“,这里是显示结果,而不是返回值。
这里的返回值是指 委托方法的返回值。
对于异步委托,线程执行结束之后,会回到线程池。
问题:
对于 Thread类新建的线程,执行完后,如何销毁呢?
4.问题:如何实现 双击击 listView 打开目录,关键点是:我不会获取 listView选中项目的路径