SimpleComposite_WPF.py


  • WPF アプリケーションとして、IronPython で実現した事例を紹介します。


# -*- coding: utf-8 -*-
#===============================================================================
# Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部
#
# History: Design Pattern
# 2008/01/25, IronPython 1.1.1 (download)
# 2008/08/22, IronPython 1.1.2 (download)
# 2008/01/15, ver.1.0, Windows Forms
# 2008/03/21, ver.2.0, WPF
# 2008/10/01, ver.2.1, IronPython 1.1.2
#===============================================================================
import clr
clr.AddReference("System")
from System import *
#
clr.AddReference("PresentationFramework")
from System.Windows import *
from System.Windows.Controls import *

EmpNode.cs


class EmpNode(TreeViewItem): # TreeNode

  • TreeNode に代えて、TreeViewItem を拡張しています。



def __init__(self, aemp):
self.Header = aemp.name # .Text
self.emp = aemp

  • Text に代えて、Header に値を設定しています。


def getEmployee(self):
return self.emp

Employee.cs


class Employee:
def __init__(self, nm, salry):
self.subordinates = [] # ArrayList
self.name = nm
self.salary = salry
《Note》参考文献との違い

  • ArrayList に代えて、組み込み型 list を利用しています。


def add(self, nm, salary=None):
if salary: # add(string nm, float salary)
emp = Employee(nm, salary)
else: # add(Employee emp)
emp = nm
self.subordinates.append(emp)
《Note》参考文献との違い

  • メソッド add(string,float)/add(Employee) を統合しています。


def getSalaries(self):
return reduce(
lambda sum, esub: sum + esub.getSalaries(),
self.subordinates,
self.salary)
《Note》参考文献との違い

  • 組み込み関数 reduce を利用しています。

Form1.cs


class SimpleComposite_WPF(Window): # Form

  • Form に代えて、Window を拡張しています。


def init(self):
self.rand = Random()
self.buildEmployeeList()
self.buildTree()


def buildEmployeeList(self):
self.prez = Employee("CEO", 200000)
marketVP = Employee("Marketing VP", 100000)
self.prez.add(marketVP)
salesMgr = Employee("Sales Mgr", 50000)
advMgr = Employee("Advt Mgr", 50000)
marketVP.add(salesMgr)
marketVP.add(advMgr)
prodVP = Employee("Production VP", 100000)
self.prez.add(prodVP)
advMgr.add("Secy", 20000)
for i in range(5):
salesMgr.add("Sales" + str(i+1), self.rand_sal(30000))
prodMgr = Employee("Prod Mgr", 40000)
shipMgr = Employee("Ship Mgr", 35000)
prodVP.add(prodMgr)
prodVP.add(shipMgr)
for i in range(3):
shipMgr.add("Ship" + str(i+1), self.rand_sal(25000))
for i in range(4):
prodMgr.add("Manuf" + str(i+1), self.rand_sal(20000))


def buildTree(self):
nod = EmpNode(aemp=self.prez)
self.EmpTree.Items.Add(nod) # .Nodes
self.addNodes(nod, self.prez)

  • Nodes に代えて、Items に子要素を追加しています。


def getNodeSum(self, node):
emp = node.getEmployee()
sum = emp.getSalaries()
self.lbSalary.Content = str(sum) # .Text

  • Text に代えて、Content に値を設定しています。


def addNodes(self, nod, emp):
for newEmp in emp.subordinates:
newNode = EmpNode(aemp=newEmp)
nod.Items.Add(newNode) # .Nodes
self.addNodes(newNode, newEmp)

  • IEnumerator に代えて、for 文を利用しています。
  • Nodes に代えて、Items に子要素を追加しています。


def rand_sal(self, sal):
rnum = self.rand.Next()
rnum = float(rnum) / Int32.MaxValue
return int(rnum * sal / 5 + sal)


def __init__(self, **args):
self.InitializeComponent()
self.init()
def InitializeComponent(self):
self.lbSalary = self._lbSalary()
self.EmpTree = self._EmpTree()
self._Controls()


def _lbSalary(self):
e = Label(
Name = "lbSalary",
Width=152, Height=24, # Size = Size(152, 24)
)
Canvas.SetLeft(e, 64) # Location = Point(64, 208)
Canvas.SetTop (e, 208)
return e

  • System.Windows.Forms.Label に代えて、System.Windows.Controls.Label を利用しています。


def _EmpTree(self):
e = TreeView(
Name = "EmpTree",
Width=224, Height=168, # Size = Size(224, 168)
)
e.SelectedItemChanged += self.EmpTree_AfterSelect # .AfterSelect
Canvas.SetLeft(e, 24) # Location = Point(32, 24)
Canvas.SetTop (e, 32)
return e

  • System.Windows.Forms.TreeView に代えて、System.Windows.Controls.TreeView を利用しています。
  • AfterSelect に代えて、SelectedItemChanged にイベントハンドラーを登録しています。


def _Controls(self):
self.Width = 292 # ClientSize = Size(292, 273)
self.Height = 273
self.Content = Canvas()
for e in self.lbSalary, self.EmpTree:
self.Content.Children.Add(e) # .Controls

  • ClientSize に代えて、Width/Height に値を設定しています。
  • Canvas 内に、各コントロールを配置します。
  • Controls に代えて、Children に子要素を追加しています。


def EmpTree_AfterSelect(self, sender, e):
self._eventLog("EmpTree_AfterSelect", sender, e) # (@.@) keep a log
node = self.EmpTree.SelectedItem # .SelectedNode
self.getNodeSum(node)

  • SelectedNode に代えて、SelectedItem の値を参照しています。

《Note》参考文献との違い

  • イベントに関するログ情報を確認できるようにしています。


def _eventLog(self, s, sender, e):
print ">>> %s"%s
for e in sender, e:
print "... %s"%e