C#在winform上實現關於treeview與listview結合項目應用


C#初學:項目實現

 

利用treeview實現左邊菜單伸縮欄,右側利用listview實現右側數據顯示,不同單項對應不同列表,當修改列表時,修改記錄會顯示在textbox文本框中。

1.實現treeview樹形目錄:

  首先,在form整體控件上添加Load事件(每當用戶加載窗體時發生),里面編寫兩個函數:this.InitTreeView(this.treeView1);(初始化樹形圖設置 )、this.AddNode(this.treeView1);(添加節點)。具體代碼如下:

 

private void InitTreeView(TreeView treeView)
  {
  treeView.CheckBoxes = false;//隱藏復選框
  treeView.FullRowSelect = true;//如果單擊某項會選擇該項及其所有子項,則為 true;如果單擊某項僅選擇項本身,則為 false。默認為 false。
  treeView.LabelEdit = false;//不能修改編輯項
  treeView.PathSeparator = "\\";//用\符號為分隔符
  treeView.ShowLines = true;//顯示連線
  treeView.ShowPlusMinus = true;//顯示+-號
  treeView.ShowRootLines = true;//是否在節點之間繪制連線
  treeView.AfterSelect += new TreeViewEventHandler(treeView_AfterSelect);//委托

  }



  public void AddNode(TreeView treeView)
  {
  //添加節點
  TreeNode node = treeView.Nodes[0];
  treeView.BeginUpdate();
  node.Nodes.Clear();

  //增加分類節點
  TreeNode node1 = new TreeNode("學生");
  TreeNode node2 = new TreeNode("老師");
  TreeNode node3 = new TreeNode("外勤");
  TreeNode node4 = new TreeNode("管理員");

  node.Nodes.Add(node1);
  node.Nodes.Add(node2);
  node.Nodes.Add(node3);
  node.Nodes.Add(node4);

  treeView.EndUpdate();

  }

 2.完成treeview和listview的過渡。完成對樹形節點目錄初步設置后,其中用到一個重要函數,判斷點不同節點會觸發何事件。不同事件對應列表不同,第一個子節點對應Teacher()事件,會有老師相關列表,屬性有姓名、性別、年齡、科目、教齡;第二個節點對應Student()事件,會有學生相關列表,屬性有姓名、性別、年齡、學科、專業;第三個子節點對應Waiqin()事件,會有外勤相關列表,屬性有姓名、性別、年齡、行業、工齡;第四個子節點對應Guanli()事件,會有管理員相關列表,屬性有姓名、性別、年齡、行業、區域;各個節點對應事件不同,列表不同。

 private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
  {

  if (e.Node.Parent != null && e.Node.Parent.Index == 0)//當前選中的節點有父節點,並且該父節點在相同級別的父節點中排行第一。
  {
  if (e.Node.Index == 0)
  {
  Teacher();
  listView1.judge = 1;//對應事件設置的一個標志,用來判斷何時對應何事件
  }
  else if (e.Node.Index == 1)
  {
  Student();
  listView1.judge = 2;
  }
  else if (e.Node.Index == 2)
  {
  Waiqin();
  listView1.judge = 3;
  }
  else
  {
  Guanli();
  listView1.judge = 4;
  }
  }
  else
  {
  }
  }

3.listview控件:不同事件對應不同列表

如:

public void Teacher()
  {
  List<Switch> nlist = new List<Switch>();//聲明
  var lines1 = File.ReadAllLines(@"excel表的路徑");//讀入excel文件數據
  listView1.Clear();//清除數據
  this.listView1.Columns.Add("A", 120, HorizontalAlignment.Left); //一步添加  添加列表項
  this.listView1.Columns.Add("B", 120, HorizontalAlignment.Left);
  this.listView1.Columns.Add("C", 120, HorizontalAlignment.Left);
  this.listView1.Columns.Add("D", 120, HorizontalAlignment.Left);
  this.listView1.Columns.Add("E", 120, HorizontalAlignment.Left);
  this.listView1.Columns.Add("F", 120, HorizontalAlignment.Left);
  foreach (var item in lines1)//foreach是循環遍歷list集合里面的元素直到遍歷完list中的所有元素遍歷list時,每次遍歷都將list集合中的元素作為var類型賦給item
  {
  string[] values = item.Split(',');//去掉逗號
  if (values[0].ToString() != "Name")//取消讀入數據不是數據內容,找到它的特點,本行讓操作內容不等於非數據內容
   {
    if (values[1].ToString() != "number")
    {
    Switch s2 = new Switch();
    s2.Name = values[0];
    s2.id = values[1];
    nlist.Add(s2);
    this.listView1.Items.Add(new ListViewItem(new String[] {s2.id,s2.Name, "李麗", "", "30", "數學" }));//填充對應老師的列表項的內容
    //ListViewItem dc = new ListViewItem();//另一種添加列表方式
    // dc.Text = s2.id;
    //dc.SubItems.Add(s2.Name);
    /*dc.SubItems.Add("正位");
    dc.SubItems.Add("單鎖");
    dc.SubItems.Add("否");
    dc.SubItems.Add("正常");*/
    //listView1.Items.Add(dc);
    }
  }
  }}

4.使列表對應項的內容可修改

思路:在listview中建一個textbox文件框,對文件進行設置,當雙擊listview控件時,觸發OnDoubleClick()事件,其中獲取屏幕工作區坐標,並根據函數可得坐標所點具體項/列,若設置一二列,不可修改,其他列可修改。藍色代表此部分不涉及相關代碼。藍色代表后續需要補充說明函數。

public ListView()
{
m_tb = new TextBox();//文件框
m_tb.Multiline = false;
m_tb.Visible = false;

this.GridLines = true;
this.FullRowSelect = true;//可選擇同行其他列
this.Controls.Add(m_tb);//這個頁面的控件集中添加一個控件
}

protected override void OnDoubleClick(EventArgs e)//鼠標雙擊空間列表
{
Point tmpPoint = this.PointToClient(Cursor.Position);//獲得鼠標所點工作區坐標
ListViewItem.ListViewSubItem subitem = this.HitTest(tmpPoint).SubItem;//
ListViewItem item = this.HitTest(tmpPoint).Item;//Item是一個整體,舉例子來說 Item就是一個文件夾 ,subItem 就是文件夾的一些屬性
//var _name = SelectedItems[0];
if (subitem != null)
{
switch (judge)
{
case 1:
case 3:
if (item.SubItems[5].Equals(subitem))
{
_error = subitem.Text;//其他中textbox2所對應文本框顯示內容
}
else
{
_start = subitem.Text;//textbox1所對應文本框顯示內容
}
break;
case 2:
if (item.SubItems[4].Equals(subitem))
{
_error = subitem.Text;
}
else
{
_start = subitem.Text;
}
break;

case 4:
if (item.SubItems[3].Equals(subitem))
{
_error = subitem.Text;
}
else
{
_start = subitem.Text;
}
break;

}

if (item.SubItems[0].Equals(subitem) || item.SubItems[1].Equals(subitem))//讓列表一二項(列)不可編輯
{
}
else
{
EditItem(subitem);//其余項可編輯,編輯函數

}
}

base.OnDoubleClick(e);
}

編輯函數:此段引用他人代碼,若有侵權,聯系刪除

private void EditItem(ListViewItem.ListViewSubItem subItem)
{
if (this.SelectedItems.Count <= 0)
{
return;
}
Rectangle _rect = subItem.Bounds;//表示一個矩形的大小和位置
m_tb.Bounds = new Rectangle(_rect.Left+2,_rect.Top+1,_rect.Width-3,_rect.Height-3);//避免網格被遮掉

m_tb.BorderStyle = BorderStyle.None;//文本框邊框類型
m_tb.BringToFront();//控件的Z順序則是控件所在的父容器上的所有控件的在該父容器得的Z軸上的排列

m_tb.Text = subItem.Text;//顯示文本內容
m_tb.Leave += new EventHandler(tb_Leave);//委托
m_tb.TextChanged += new EventHandler(m_tb_TextChanged);
m_tb.Visible = true;//是否顯示控件
m_tb.Tag = subItem;//獲取有關控件的數據對象
m_tb.Select();//激活控件

}

private void tb_Leave(object sender, EventArgs e)
{
m_tb.TextChanged -= new EventHandler(m_tb_TextChanged);
(sender as TextBox).Visible = false;

}

private void m_tb_TextChanged(object sender, EventArgs e)//文字改變
{
if ((sender as TextBox).Tag is ListViewItem.ListViewSubItem)
{
(this.m_tb.Tag as ListViewItem.ListViewSubItem).Text = this.m_tb.Text;
Point tmpPoint = this.PointToClient(Cursor.Position);
ListViewItem.ListViewSubItem subitem = this.HitTest(tmpPoint).SubItem;
ListViewItem item = this.HitTest(tmpPoint).Item;
if (subitem != null)
{
switch (judge)
{
case 1:
case 3:
if (item.SubItems[5].Equals(subitem))
{
_finish = this.m_tb.Text;
}
else
{
_end = this.m_tb.Text;
}
break;
case 2:
if (item.SubItems[4].Equals(subitem))
{
_finish = this.m_tb.Text;
}
else
{
_end = this.m_tb.Text;
}
break;

case 4:
if (item.SubItems[3].Equals(subitem))
{
_finish = this.m_tb.Text;
}
else
{
_end = this.m_tb.Text;
}
break; } }
}

}

5.使修改記錄textbox1和其他textbox2顯示響應修改過程,此步涉及到前面藍色部分,以textbox1修改記錄為例。

private void textBox1_Click_1(object sender, EventArgs e)
        {
            string operation;//修改記錄
            DateTime t = DateTime.Now;      //獲取當前時間,格式為“年/月/日 星期 時/分/秒”
             if (listView1.SelectedItems.Count > 0)
            {
                operation = "時間:" + t + " " + "名字:" + listView1.SelectedItems[0].SubItems[1].Text + " " + "改變狀態:" + listView1._start + "--->"
 + listView1._end + "\r\n";//listView1.SelectedItems[0].SubItems[1].Text 抓取鼠標所在行具體第幾項(列)文本,listView1._start 和 listView1._end 藍字部分已求出
      textBox1.AppendText(operation);//textbox1中添加新內容 
      Application.DoEvents();//刷新 } 
    }

6.存在問題

1.在listview里用textbox,雖然實現可編輯,但是有點丑並且文本框會出現可能不會跟隨列表移動的問題。

2.有些代碼重復利用,不知如何優化

3.在修改記錄textbox1內,每點擊一次都會重復一次記錄生成,需要找到若不做修改不生成記錄;textbox1修改記錄與textbox2其他兩個事件一般僅發生一件,不可同時發生,即不可同時生成記錄,暫未找到方法。

4.可嘗試用datagridview控件。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM