Gtk.TreeView (2)

根據昨天的程式,稍作改良,就可以把整個目錄樹丟進去顯示了…
下面就是利用 Recursive 來把資料塞到 TreeStore 裡面去。

public void _buildTreeStore( TreeStore store, DirectoryInfo di, TreeIter parent )
{
foreach( DirectoryInfo iter in di.GetDirectories() )
{
TreeIter ti = store.AppendValues( parent, iter.FullName, iter.Name, "" );
_buildTreeStore( store, iter, ti, true  );
}
// add files in tree
foreach( FileInfo fi in di.GetFiles() )
store.AppendValues( parent, fi.FullName, fi.Name, fi.Length.ToString() );
}
public TreeStore buildTreeStore( string path )
{
// 0: fullpath 1: name 2: filesize
TreeStore store = new TreeStore( typeof(string), typeof(string), typeof(string) );
DirectoryInfo di = new DirectoryInfo( path );
TreeIter root = store.AppendValues( path, di.Name, "" );
_buildTreeStore( store, di, root );
return store;
}
public ExplorerSharp(): base(Gtk.WindowType.Toplevel)
{
Build();
TreeStore store = buildTreeStore( "./" );
// 設定資料來源
treeview1.Model = store;
// 不顯示表頭
treeview1.HeadersVisible = false;
// 設定要顯示的欄位
treeview1.AppendColumn("Name", new CellRendererText(), "Name", 1 );
treeview1.AppendColumn("Size", new CellRendererText(), "FileSize", 2 );
// 一次只能選定一列或一個節點
treeview1.Selection.Mode = Gtk.SelectionMode.Single;
}

Gtk.TreeView (1)

使用 TreeView 的基本,首先就是添加列與設定要顯示的欄。
呈現的方式,取決於你給 TreeView.Model 屬性的資料是什麼,如果是 TreeStore,就會顯示 Tree,如果是 ListStore,就會顯示 Grid。

// 如果你把 TreeStore 改為 ListStore,就能得到類似 Grid 的效果。
TreeStore store = new TreeStore();
for( int i=0; i<10; i++ )
{
TreeIter iter = store.AppendValues( "Demo " + i.ToString(), "" );
// 添加子節點,你可以把這兩行註解掉試試看,這樣就沒有子節點了。
for( int j=0; j<10; j++ )
store.AppendValues( iter, "", "Child " + j.ToString() );
}
// 設定資料來源
treeview1.Model = store;
// 不顯示表頭
treeview1.HeadersVisible = false;
// 設定要顯示的欄位
treeview1.AppendColumn("Name", new CellRendererText(), "i", 0 );
treeview1.AppendColumn("Size", new CellRendererText(), "j", 1 );
// 一次只能選定一列或一個節點
treeview1.Selection.Mode = Gtk.SelectionMode.Single;

Gtk.TreeView

這幾天玩MonoDevelop Stetic (gtk# 的 UI designer) 的時候,發現 gtk# 裡的 TreeView Widget 是個很有趣的元件。
有趣的原因,是因為他的設計哲學整個跟 Windows form 的設計哲學截然不同,Windows form 的 TreeView 就是很單純的 TreeView,沒別的。
而 gtk# 的 TreeView Widget 則是以所謂的 MVC Pattern 去設計,所以,其實 TreeView Widget 會根據你塞進去的 Store (Model) 來決定該怎麼去顯示。也因此,它既可以當作 Grid 來用,也可以當作 TreeView 來用,也可以當作有 TreeView 的 Grid 來用。
摸索的時候,花了不少時間,但今天打算寫這篇的時候,發現Mono官方網站就有 Tutorial:GtkSharp TreeView Tutorial,真的是白白浪費了摸索的時間…

如何在 Ubuntu/Debian 下重新編譯 mono/monodevelop

謝謝你,Dale E. Moore:[MonoDevelop] Can’t keep monodevelop running
信內所提供的方法,真是相當簡單又快速,也讓我學到 apt-get 的另外一個用法:build-dep

sudo apt-get build-dep mono monodevelop
Download mono-1.2.5.2.tar.bz2<http://go-mono.com/sources/mono/mono-1.2.5.2.tar.bz2>and monodevelop-0.17.tar.bz2<http://go-mono.com/sources/monodevelop/monodevelop-0.17.tar.bz2>from http://go-mono.com/sources-stable/.
bunzip2 mono-1.2.5.2.tar.bz2
tar xvf mono-1.2.5.2.tar.bz2
cd mono-1.2.5.2
./configure --prefix=`pkg-config --variable=prefix mono`
make
sudo make install
bunzip2 monodevelop-0.17.tar.bz2
tar xvf monodevelop-0.17.tar
cd monodevelop-0.17
./configure --prefix=`pkg-config --variable=prefix mono`
make
sudo make install

.Net framework 2.0 SP1/3.0 SP1/3.5 無法安裝

前一陣子Microsoft釋出了Visual Studio 2008/.Net framework 3.5,前兩天想裝起來看看,只是怎麼裝都不行。
經過與Google明查暗訪的結果,都說要先移除掉先前安裝的所有 .Net frameowrk以及登錄檔(Registry)裡面的資訊,再重新安裝才行。
還好,MicrosoftAaron Stebner寫了一個工具,可以幫你作掉這些麻煩事,也因為這個工具,我先移除了先前安裝的 .Net framework 3.0,再移除掉 .Net framework 2.0,接著依序安裝 .Net framework 2.0 SP1、.Net framework 3.0 SP1、.Net framework 3.5,就大功告成了。
關於這個工具的文章與下載網址:Aaron Stebner’s WebLog : Automated cleanup tool to remove the .NET Framework 1.0, 1.1, 2.0, 3.0 and 3.5

新版 mod_mono 在啟動時的警告

最近在重新啟動Apache httpd時,常出現這錯誤訊息(我的環境:CentOS 4.5):

Starting httpd: [Tue Oct 30 07:39:41 2007] [crit] The unix daemon module not initialized yet. Please make sure that your mod_mono module is loaded after the User/Group directives have been parsed. Not initializing the dashboard.

今天早上認真地向Google祈禱了一下,發現有人問過了:[Mono-list] Errors after update….:(
解決方法很簡單,就是打開你的 httpd.conf,確定

User apache
Group apache

Include conf.d/*.conf

之前即可。

How to monorail by Generator tool(1)

環境:Windows 2000/XP
需求:

  1. 利用Subversion(或TortoiseSVN checkout Generator 出來,網址:http://svn.castleproject.org:8080/svn/castle/trunk/Tools/Generator/
  2. 進行編譯與安裝:nant install,這個步驟會將 monorail.bat 與 generator.bat 這兩個批次檔安裝到 c:\winnt 或 c:\windows 下。
  3. 切換到你的工作目錄,執行 monorail your_project,就會自動幫你產生出 your_project 這個目錄,裡面就是完整的框架。
  4. 切換到 your_project 目錄下,執行 nant setup,這個步驟會自動幫你下載官方網站上的 rc2 版本下來進行設定,如果你想要使用最新的組件,可以修改 default.build 裡面的 castle.url,將他改為官方 build server 上提供的網址(每日更新),如:
    <property name="castle.url" value="http://builds.castleproject.org/builds/castleproject-1.1-build_456-net-2.0-debug.zip" />

    ;或是本地端位置

    <property name="castle.url" value="file://c:\download\Castle-net-2.0-debug-2007-7-30 (r4074).zip" />
  5. 修改 public/web.config,第18行多了 <services> 將這行移除或註解掉。
  6. Mono 目錄下的 booi.bat 複製到 your_project 目錄下,script 目錄下的批次檔都會用到,所以複製到這邊以後會比較省事。
  7. 修改 script\server.bat為如下內容,如果你不修改的話,Webdev.WebServer.exe 雖然可以順利執行,但卻會出錯。
    @booi script\server.boo %windir%\Microsoft.NET\Framework\v2.0.50727\Webdev.WebServer.exe norestart /port:8080 /path:%CD%\public
  8. 執行 script\server,右下角會有 Webdev.WebServer.exe 的 trayicon 出現,告訴你可以用了。打開瀏覽器吧,在網址列輸入 http://localhost:8080/index.html 就可以看到畫面囉~

除了以上的步驟,產生出來的專案目錄下有個 README.TXT,你也可以好好地閱讀一下。

ActiveRecord SessionScope/Transaction

ActiveRecord是很方便沒錯,只是如果你要處理大量時,底層的NHibernate會以你意想不到的方式去逐條更新資料表格,可想而知,這很慢~
幸好官方有提供了文件(Using Scopes :: Castle Project, Understanding Scopes :: Castle Project),告知你如何利用SessionScope來完成批次處理,也就是先行處理完畢以後,再一次寫入,這樣子速度就可以達到一定程度的提昇。

如何使用 Mono.GetOptions?

Mono.GetOptions 是做什麼的?問的好。
如果你曾經在 Linux 下開發過 console 應用程式,相信你對於getopt這個 library 應該不陌生才對。
Mono.GetOptions 就是一個類似 getopt 的組件。

這裡主要是介紹怎麼使用,下面就列出步驟:

  1. 安裝Mono
  2. 在 AssemblyInfo.cs 裡面加入:
    //填入簡單的用法說明,顯示 help 時會用到
    [assembly: Mono.UsageComplement("[-t:param] [-o] [-h] [-v] [-u]")]
    //填入關於這程式的說明,也是顯示 help 時會用到
    [assembly: Mono.About("A sample about how to use Mono.GetOptions")]
    //作者
    [assembly: Mono.Author("your_name")]
    //有錯誤時可以通報誰,可填可不填
    [assembly: Mono.ReportBugsTo("your_name@your_domain.com")]
    //更詳細的說明,可填可不填
    [assembly: Mono.AdditionalInfo("This is a sample about how to use Mono.GetOptions.  It's only a small program.  If you want to know more about Mono.GetOptions, you can hack Mono.GetOptions source code.")]
    //是屬於哪個套件,可填可不填
    [assembly: Mono.IsPartOfPackage("Samples")]
    

    然後在原來的地方應該會有這些:

    [assembly: AssemblyTitle("Mono.GetOptions Sample")]
    [assembly: AssemblyProduct("getoptions_sample")]
    [assembly: AssemblyCopyright("your_name or your_organization")]
    [assembly: AssemblyVersion("1.0.*")]
    

    請記得都填入。

  3. 引用 Mono.GetOptions 組件,用SharpDevelop的話,可以很方便的選 Add mono reference。
  4. 記得 using Mono.GetOptions。
    using Mono.GetOptions;
  5. 新增一個類別,繼承 Options。
    using System.Collections.Generic;
    class ProgramOptions : Options
    {
    private string _outputFolder = "output";
    public string OutputFolder
    {
    get { return _outputFolder; }
    set { _outputFolder = value; }
    }
    private List _templateFolders;
    // 表示最多容許兩個,參數可以用 -t 或是 --template
    // 用法大致是 -t:test 或 --template:test
    [Option(2, "Template folder, default is 'default'", 't', "template")]
    public WhatToDoNext DoTemplate( string s )
    {
    //Console.WriteLine( "template={0}", s );
    _templateFolders.Add( s );
    return WhatToDoNext.GoAhead;
    }
    // 預設只容許一個,參數是 -o 或 --output
    [Option("Output folder, default is 'output'", 'o', "output")]
    public WhatToDoNext DoOutput( string s )
    {
    //Console.WriteLine( "output={0}", s );
    _outputFolder = s;
    return WhatToDoNext.GoAhead;
    }
    public ProgramOptions()
    {
    // 表示同時接受 Linux / Windows 的命令列常態用法
    this.ParsingMode = OptionsParsingMode.Both;
    _templateFolders = new List();
    }
    }
    
  6. 在 Main 裡面使用剛剛新增的類別:
    ProgramOptions options = new ProgramOptions();
    options.ProcessArgs(args);
    foreach( string s in options.TemplateFolders )
    Console.WriteLine( "Template folder = {0}", s );
    Console.WriteLine( "Output folder = {0}", options.OutputFolder );
    

    就這麼簡單。

  7. Build 以後,你可以在命令列模式或是 linux 的 console 模式下試試看了~這邊我假設你編譯出來的目的檔是 your_program:
    $your_program -h
    $your_program --help
    $your_program --template:t1 --template:t2 --output:o1
    $your_program -t:t1 -t:t2 -o:o1
    $your_program -u
    $your_program -V
    $your_program --version
    

getopt有興趣的話,可以參考getopt
這是對岸同志寫的介紹,很簡短:

  • Mono项目提供的一个控制台程序辅助包GetOptions – 自由、创新、研究、探索…… – 博客园
  • 這篇也是 Tutorial,寫的很好:The PumaCode.org Blog :: GetOpt style command line processing in C# with Mono.GetOptions

    如何在 CentOS 4/4.5 裡安裝 mono

    這裡,我假設你用 yum 來管理你的套件。

    1. 下載 mono.repo 然後放到 /etc/yum.repos.d/ (以 root 身份)
    2. #yum update
    3. #yum install mono-complete xsp mod_mono
    4. 完成啦!

    很簡單,對吧~
    如果你用 Fedora Core 3/4/5 或者是 RHEL 4,你可以參考Mono 下載頁面
    安裝的方法跟上面所說得非常地類似。