Windows 7 で IronPython そのさん

WPF にてコードでメニューを作る方法がイマイチ解らない。
というか作れたとしてどう考えてもベタ打ちな方法しかできないだろう。

ここは GtkUIManager のように XML で綺麗に作りたい。
そのための XAML じゃないか!
でもメニューとか個別パーツのみを XAML にするってできるのかな?

ということでやってみた。

いくら探しても文字列から XAML を読み込む方法が見つからない。
CLR にはデルヒャァの TStringStream みたいなのは無いの?
しかたがないので XAML ファイルを別に用意する。

<Menu
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <MenuItem Header="ファイル(_F)">
        <MenuItem Header="開く(_O)" InputGestureText="Ctrl+O" Name="menu_open" />
        <Separator/>
        <MenuItem Header="終了(_Q)" InputGestureText="Ctrl+Q" x:Name="menu_close" />
    </MenuItem>
</Menu>

というメニューのみの XAML を仮に作ってみた。
一番の親に CLR 名前空間定義は必須のようです。

IronPython はコンパイルしないので InitializeComponent() できない。
ので XAML 内でハンドラ指定はできないようだ、いくら試してもエラーばかり。
とりあえず上記に ui.xaml という名前を付けて。

# -*- coding: UTF-8 -*-

import sys
import clr

clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")

from System import *
from System.Windows import *
from System.Windows.Controls import *
from System.IO import *
from System.Windows.Markup import XamlReader

class MoviePlayer(Window):
    def __init__(self):
        self.Title = "メニューだよ"
        # Menu を GtkUIManager 風に読み込む
        # ようにしたいけど今はこれが精一杯
        i = sys.argv[0].rindex("\\")
        xaml_path = sys.argv[0][:i] + "\\ui.xaml"
        f = FileStream(xaml_path, FileMode.Open, FileAccess.Read)
        _menu = XamlReader.Load(f)
        DockPanel.SetDock(_menu, Dock.Top)
        _menu.Items[0].Items[0].Click += self.on_open
        _menu.Items[0].Items[2].Click += self.on_close
        # DockPanel
        dpanel = DockPanel()
        dpanel.LastChildFill = False
        dpanel.Children.Add(_menu)
        # self
        self.Content = dpanel
        self.Width = 320
        self.Height = 240

    def on_open(self, sender, e):
        MessageBox.Show("わーい")

    def on_close(self, sender, e):
        self.Close()

if __name__ == "__main__":
    a = Application()
    a.Run(MoviePlayer())

menu_first

何をやっているかはなんとなく解ると思う。
とりあえずパーツのみの XAML は可能だと解った。
少しだけ GtkUIManager 風に作れたが Items の順番でハンドラ指定では…

ウインドを作る( PyGtk+Glade )

の最後みたいな処理を作るしかないかな?それはそれで難しくは無いけど。
もっと Name プロパティからスマートに指定できそうなんだけど…続くかも。