返回介绍

Advanced Controls in Mono Winforms

发布于 2025-02-22 22:19:49 字数 13345 浏览 0 评论 0 收藏 0

In this part of the IronPython Mono Winforms tutorial, we introduce some more advanced controls. Namely the ListBox , the ListView and the TreeView control.

ListBox Control

The ListBox control is used to display a list of items. Users can select one or more items by clicking on them.

listbox.py

#!/usr/bin/ipy

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")

from System.Windows.Forms import Application, Form, StatusBar
from System.Windows.Forms import ListBox, DockStyle
from System.Drawing import Size


class IForm(Form):

  def __init__(self):
    self.Text = "ListBox"
    
    lb = ListBox()
    lb.Parent = self

    lb.Items.Add("Jessica")
    lb.Items.Add("Rachel")
    lb.Items.Add("Angelina")
    lb.Items.Add("Amy")
    lb.Items.Add("Jennifer")
    lb.Items.Add("Scarlett")

    lb.Dock = DockStyle.Fill
    lb.SelectedIndexChanged += self.OnChanged

    self.sb = StatusBar()
    self.sb.Parent = self

    self.Size = Size(220, 220)
    self.CenterToScreen()
  

  def OnChanged(self, sender, event):
    self.sb.Text = sender.SelectedItem


Application.Run(IForm())

Our example shows a listbox with six names. The selected item is shown in the statusbar.

lb = ListBox()
lb.Parent = self

ListBox control is created.

lb.Items.Add("Jessica")

This is how we add a new item to the ListBox control. The control has the Items property. The property is a reference to the list of items in a listbox. Using this reference, we can add, remove or get count of items of the listbox.

lb.SelectedIndexChanged += self.OnChanged

SelectedIndexChanged event is triggered, when we select an item.

def OnChanged(self, sender, event):
  self.sb.Text = sender.SelectedItem

Inside the OnChange() method, we get selected value of the listbox and set it to the statusbar.

ListBox
Figure: ListBox

ListView

ListView control is used to display collections of items. It is a more sophisticated control than the ListBox control. It can display data in various views. It is mostly used to display data in multicolumn views.

listview.py

#!/usr/bin/ipy

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")

from System.Windows.Forms import Application, Form, StatusBar
from System.Windows.Forms import ListView, View, ColumnHeader
from System.Windows.Forms import ListViewItem, DockStyle, SortOrder
from System.Drawing import Size


class IForm(Form):

  def __init__(self):
    self.Text = 'ListBox'
     

    actresses = { 'Jessica Alba' : '1981', 'Angelina Jolie' : '1975', 
      'Natalie Portman' : '1981', 'Rachel Weiss' : '1971', 
      'Scarlett Johansson' : 1984 }


    name = ColumnHeader()
    name.Text = 'Name'
    name.Width = -1
    year = ColumnHeader()
    year.Text = 'Year'

    self.SuspendLayout()

    lv = ListView()
    lv.Parent = self
    lv.FullRowSelect = True
    lv.GridLines = True
    lv.AllowColumnReorder = True
    lv.Sorting = SortOrder.Ascending
    lv.Columns.AddRange((name, year))
    lv.ColumnClick += self.OnColumnClick

    for act in actresses.keys():
      item = ListViewItem()
      item.Text = act
      item.SubItems.Add(str(actresses[act]))
      lv.Items.Add(item)
    

    lv.Dock = DockStyle.Fill
    lv.Click += self.OnChanged

    self.sb = StatusBar()
    self.sb.Parent = self
    lv.View = View.Details

    self.ResumeLayout()

    self.Size = Size(350, 300)
    self.CenterToScreen()
  

  def OnChanged(self, sender, event):

    name = sender.SelectedItems[0].SubItems[0].Text
    born = sender.SelectedItems[0].SubItems[1].Text
    self.sb.Text = name + ', ' + born
  

  def OnColumnClick(self, sender, event):

    if sender.Sorting == SortOrder.Ascending:
      sender.Sorting = SortOrder.Descending
    else: 
      sender.Sorting = SortOrder.Ascending


Application.Run(IForm())

In our example, we have a list view with two columns. In the first column, we display the name of the actress. In the second one their date of birth. The data is store in a List collection. By selecting a row, the data in a row is displayed in the statusbar. Also, by clicking on the column header, the data is sorted.

actresses = { 'Jessica Alba' : '1981', 'Angelina Jolie' : '1975', 
  'Natalie Portman' : '1981', 'Rachel Weiss' : '1971', 
  'Scarlett Johansson' : 1984 }

We store our data in the actresses dictionary.

name = ColumnHeader()
name.Text = 'Name'
name.Width = -1

For each column in a list view, we create a ColumnHeader . By setting the Width to -1, the width of the column is equal to the longest item in the column.

lv = ListView()
lv.Parent = self

ListView control is created.

lv.FullRowSelect = True
lv.GridLines = True
lv.AllowColumnReorder = True
lv.Sorting = SortOrder.Ascending

Here we set four properties of the control. This code lines enable full row selection, show grid lines, allow column reordering by dragging the columns and sort the data in ascending order.

lv.Columns.AddRange((name, year))

Here we add two ColumnHeader s to the ListView control.

for act in actresses.keys():
  item = ListViewItem()
  item.Text = act
  item.SubItems.Add(str(actresses[act]))
  lv.Items.Add(item)

This cycle populates the list view control. Each row is added to the list view as a ListViewItem class.

lv.View = View.Details

The ListView control can have different views. Different views display data differently.

name = sender.SelectedItems[0].SubItems[0].Text
born = sender.SelectedItems[0].SubItems[1].Text
self.sb.Text = name + ', ' + born

Inside the OnChanged() method, we get the data from the selected row and show it on the statusbar.

if sender.Sorting == SortOrder.Ascending:
  sender.Sorting = SortOrder.Descending
else: 
  sender.Sorting = SortOrder.Ascending

Here we toggle the sorting order of the column.

ListView
Figure: ListView

TreeView

TreeView control displays hierarchical collection of items. Each item in this control is represented by a TreeNode object.

treeview.py

#!/usr/bin/ipy

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")

from System.Windows.Forms import Application, Form, StatusBar
from System.Windows.Forms import TreeView, TreeNode, DockStyle
from System.Drawing import Size


class IForm(Form):

  def __init__(self):
    self.Text = 'TreeView'
    
    tv = TreeView()

    root = TreeNode()
    root.Text = 'Languages'

    child1 = TreeNode()
    child1.Text = 'Python'

    child2 = TreeNode()
    child2.Text = 'Ruby'

    child3 = TreeNode()
    child3.Text = 'Java'

    root.Nodes.AddRange((child1, child2, child3))

    tv.Parent = self
    tv.Nodes.Add(root)
    tv.Dock = DockStyle.Fill
    tv.AfterSelect += self.AfterSelect

    self.sb = StatusBar()
    self.sb.Parent = self

    self.Size = Size(220, 220)
    self.CenterToScreen()
  

  def AfterSelect(self, sender, event):  
    self.sb.Text = event.Node.Text
  

Application.Run(IForm())

This is a very simple demonstration of the TreeView control. We have one root item and three children.

tv = TreeView()

We create the TreeView control.

root = TreeNode()
root.Text = 'Languages'
...
tv.Nodes.Add(root)

Here we create a root node.

child1 = TreeNode()
child1.Text = 'Python'

Child node is created in a similar way.

root.Nodes.AddRange((child1, child2, child3))

Child nodes are plugged into the Nodes property of the root node.

TreeView
Figure: TreeView

Directories

The following code example will examine the TreeView control more in-depth.

directories.py

#!/usr/bin/ipy

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")

from System.Windows.Forms import Application, Form, StatusBar
from System.Windows.Forms import Button, TreeView, TreeNode
from System.Windows.Forms import DockStyle, AnchorStyles
from System.Drawing import Size, Point
from System.IO import Directory, DirectoryInfo


HOME_DIR = '/home/vronskij'

class IForm(Form):

  def __init__(self):
    self.Text = 'Directories'
    self.Size = Size(400, 400)
    
    self.tv = TreeView()

    self.SuspendLayout()

    self.tv.Parent = self
    self.tv.Location = Point(10,10)
    self.tv.Size = Size(self.ClientSize.Width - 20, self.Height - 200)
    self.tv.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right 


    self.tv.FullRowSelect = False
    self.tv.ShowLines = True
    self.tv.ShowPlusMinus = True
    self.tv.Scrollable = True  
    self.tv.AfterSelect += self.AfterSelect

    expand = Button()
    expand.Parent = self
    expand.Location = Point(20, self.tv.Bottom + 20)
    expand.Text = 'Expand'
    expand.Anchor = AnchorStyles.Left | AnchorStyles.Top
    expand.Click += self.OnExpand

    expandAll = Button()
    expandAll.Parent = self
    expandAll.Location = Point(20, expand.Bottom + 5)
    expandAll.Text = 'Expand All'
    expandAll.Anchor = AnchorStyles.Left | AnchorStyles.Top
    expandAll.Click += self.OnExpandAll

    collapse = Button()
    collapse.Parent = self
    collapse.Location = Point(expandAll.Right + 5, expand.Top)
    collapse.Text = 'Collapse'
    collapse.Anchor = AnchorStyles.Left | AnchorStyles.Top
    collapse.Click += self.OnCollapse

    collapseAll = Button()
    collapseAll.Parent = self
    collapseAll.Location = Point(collapse.Left, collapse.Bottom + 5)
    collapseAll.Text = 'Collapse All'
    collapseAll.Anchor = AnchorStyles.Left | AnchorStyles.Top
    collapseAll.Click += self.OnCollapseAll

    self.sb = StatusBar()
    self.sb.Parent = self

    self.ShowDirectories(self.tv.Nodes, HOME_DIR)

    self.ResumeLayout()

    self.CenterToScreen()
  
  def AfterSelect(self, sender, event):
  
    self.sb.Text = event.Node.Text
    
  def ShowDirectories(self, trvNode, path):
  
    dirInfo = DirectoryInfo(path)
    if (dirInfo != None):
    
      subDirs = dirInfo.GetDirectories()
      tr = TreeNode(dirInfo.Name)

      if (subDirs.Length > 0):
      
        for dr in subDirs: 
          if not dr.Name.StartsWith("."):
            self.ShowDirectories(tr.Nodes, dr.FullName)
            
      trvNode.Add(tr)  

    
  def OnExpand(self, sender, event):
    self.tv.SelectedNode.Expand()
  

  def OnExpandAll(self, sender, event):
    self.tv.ExpandAll()
  

  def OnCollapse(self, sender, event):
    self.tv.SelectedNode.Collapse()
  

  def OnCollapseAll(self, sender, event):
    self.tv.CollapseAll()


Application.Run(IForm())

Our code example shows the directories of the specified home directory in a TreeView control. The application starts with some delay, because it reads the directory structure of the home directory first. We have also four buttons on the form. The buttons expand and collapse nodes programatically.

self.tv.Scrollable = True 

We make the treeview control scrollable, because the control shows lots of directories.

self.ShowDirectories(self.tv.Nodes, HOME_DIR)

The ShowDirectories() method fills the nodes of the treview control with directories available in the specified home directory.

if (subDirs.Length > 0):
  ...

We check if there are any subdirectories.

for dr in subDirs: 
  if not dr.Name.StartsWith("."):
    self.ShowDirectories(tr.Nodes, dr.FullName)

We loop through all directories. For this, we use the recursion algorithm. We also skip the hidden directories. They begin with a dot on Unix systems.

trvNode.Add(tr)   

This code line actually adds the directory to the treeview control.

def OnExpand(self, sender, event):
  self.tv.SelectedNode.Expand()

All four buttons have events plugged to a method. Here is a method for the Expand button. It calls the Expand() method of the currently selected node.

Directories
Figure: Directories

In this part of the IronPython Mono Winforms tutorial, we covered several advanced controls available in Winforms programming library.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文