#title(.NETプログラミング研究 第27号)

#navi(.NET プログラミング研究)

#contents

*.NETプログラミング研究 第27号 [#f6b96503]

**ピンポイントリンク [#z63244db]

***Docking Windowを使う [#jf10af1d]

#column(注意){{
この記事の最新版は「[[.NETでDocking Windowを使う>http://dobon.net/vb/dotnet/links/dockingwindow.html]]」で公開しています。
}}

Visual Studio .NETのメインウィンドウの上下左右には、ツールボックス、ソリューションエクスプローラ、プロパティウィンドウなどがくっついており、これらはドラッグすることにより、分離させてウィンドウにしたり、別の位置にドッキングさせたり、サイズを変えたりすることが出来るようになっています。このようなウィンドウをDocking Windowと呼びます。ここでは、.NETでDocking Windowを可能にするライブラリを紹介します。(ここでは無料で使用できるものしか紹介しません。)

何をおいてもまず初めに紹介しなければならないのが、Phil Wrightさんの「Magic Library」にある「Magic Docking」です。

-[[DotNetMagic>http://www.dotnetmagic.com/]]
-[[The Code Project - Magic Docking - VS.NET Style>http://www.codeproject.com/cs/miscctrl/magicdocking.asp]]

このMagic Dockingは、オープンソースの.NET用IDEとして有名な「SharpDevelop」でも使用されていることからも、その信頼度の高さがうかがい知れます。

-[[SharpDevelop>http://www.icsharpcode.net/OpenSource/SD/]]

Magic Dockingはとにかく高機能です。Visual Studio .NETのDocking Windowと見た目が似ているだけでなく、「自動的に隠す」機能(右上のピンのマークをクリックすることにより、Windowが自動的に隠れ、マウスを持っていくことにより、再び表示できる機能)や、タブとしてドッキングさせる機能、Docking Windowの状態をXMLファイルやバイト型配列に保存し、復元する機能など、申し分ありません。

使い方も簡単です。「MagicLibrary.DLL」を「参照設定」に追加し、次のようなコードをフォームのLoadイベントハンドラ(またはコンストラクタ)に書くだけで、Docking Windowができてしまいます。(たった4行!!)

#code(csharp){{
//using Crownwood.Magic.Common;
//using Crownwood.Magic.Docking;
//が宣言されているものとする

private DockingManager _dockingManager = null;

//フォームのLoadイベントハンドラ
private void Form1_Load(object sender, System.EventArgs e)
{
	//DockingManagerオブジェクトの作成
	_dockingManager = new DockingManager(this, VisualStyle.IDE);
	//Contentとして新しく作成したRichTextBoxコントロールを追加
	_dockingManager.Contents.Add(new RichTextBox(), "RichTextBox");
	//Contentを表示
	_dockingManager.ShowContent(
		_dockingManager.Contents["RichTextBox"]);
}
}}

#code(vbnet){{
'Imports Crownwood.Magic.Common
'Imports Crownwood.Magic.Docking
'が宣言されているものとする

Private _dockingManager As DockingManager = Nothing

'フォームのLoadイベントハンドラ
Private Sub Form1_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load
    'DockingManagerオブジェクトの作成
    _dockingManager = New DockingManager(Me, VisualStyle.IDE)
    'Contentとして新しく作成したRichTextBoxコントロールを追加
    _dockingManager.Contents.Add(New RichTextBox, "RichTextBox")
    'Contentを表示
    _dockingManager.ShowContent( _
		_dockingManager.Contents("RichTextBox"))
End Sub
}}

このようにMagic Dockingの使用は決して難しいものではありませんが、Visual Studio .NETのフォームデザイナを使って設定できるようになればもっと便利になるかもしれません。それを可能にするのが、Jerry Maguireさんの「DockingManagerExtender」です。これを使えば、コードを自分で一行も書く必要がなくなります。

-[[The Code Project - Magic Library Docking Manager Designer>http://www.codeproject.com/cs/miscctrl/dockingmanagerextender.asp]]

使い方は、「MagicLibrary.DLL」が「参照設定」に追加された状態で、「ツールボックス」の「コンポーネント」に「DockingManagerExtender.DLL」を追加し、これをフォームに貼り付けるだけです。フォームに貼り付けたDockingManagerExtenderのContainerControlプロパティを適当に設定し(通常は貼り付けたフォームとなるでしょう)、Docking Windowとするコントロールの「DockingManagerExtenderのADockingEnable」プロパティをTrueとすれば、Docking Windowが出来上がります。

このようにMagic Dockingは、まさに最強といえますが、残念なことに、Magic Libraryは有料化され、「DotNetMagic」となりました。(有料化は私個人としては残念ですが、サポートが受けられるようになったということでは、むしろうれしく思う人も多いかもしれません。)バージョン1.7.4までのMagic Libraryは今まで通り無料で使用できますが、少なくともバージョン1.7.4は私の知る限り、どこにも公開されていないようです。(上記「The Code Project - Magic Docking - VS.NET Style」からバージョン1.7.0がダウンロードできるようです。MagicLibrary.DLLはSharpDevelopなどに含まれているので、今のとことは簡単に入手できます。)

Magic Dockingと同様の見た目と機能を持つライブラリに、Weifen Luoさんの、「DockManager Control」があります。DockManager ControlはMDIフォームに対するドッキングを可能とすることを目的としているそうです。(最新バージョンは1.2.3。)

-[[The Code Project - DockManager Control>http://www.codeproject.com/cs/miscctrl/DockManager.asp]]
-[[DockManager Control>http://www.freewebs.com/weifenluo/DockManager.htm]]
-[[GotDotNet User Sample: DockManager Control>http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=BD028D17-5E18-472E-9022-E7A4D9CDE263]]

DockManager Controlでは、Docking WindowとなるContentクラスがSystem.Windows.Forms.Formクラスを継承しているため、Docking Windowのデザインをフォームデザイナで行えます。

DockManager Controlをちょっと使ってみましょう。まず、「ツールボックス」の「コンポーネント」に「WeifenLuo.WinFormsUI.dll」を追加します。「DockManager」をフォームに貼り付け、DockプロパティをFillにしておきます(しなくても結構です)。このDockManagerの部分にDocking Windowがドッキングされます。

次にDocking Windowを作成します。「新しい項目の追加ダイアログ」を表示し、「継承されたフォーム」を選択後、「開く」をクリックします。「継承ピッカー」の「参照」をクリックし、「WeifenLuo.WinFormsUI.dll」を選択後表示される「Content」を選択し、OKをクリックします。これで作成されるクラスがDocking Windowとなりますので、フォームデザイナで適当にデザインしましょう。

作成したDocking Windowを表示させるには、Showメソッドを使用します。次の例では、DockManagerオブジェクトdockManager1に、Docking WindowのForm2を左端にドッキングされた状態で表示させています。

#code(csharp){{
//Docking WindowのForm2オブジェクトの作成
Form2 f2 = new Form2();
//dockManager1の左端にドッキングされて表示する
f2.Show(dockManager1, WeifenLuo.WinFormsUI.DockState.DockLeft);
}}

#code(vbnet){{
'Docking WindowのForm2オブジェクトの作成
Dim f2 As New Form2
'dockManager1の左端にドッキングされて表示する
f2.Show(dockManager1, WeifenLuo.WinFormsUI.DockState.DockLeft)
}}

DockManager ControlはMagic Dockingと互角の機能をもっており、便利なコントロールですが、まだまだバグが多いようです。

Docking Windowを可能にするライブラリはまだまだあります。以下にずらずら並べて見ます。(ほとんどが私は実際に試していません。)

-[[A Docking control that can be dragged and resized by the user: By Phil Wright>http://www.codeproject.com/cs/menu/dockingcontrol.asp]]

これは、Magic Dockingの作者Phil Wrightさんがそれ以前に作成したコントロールであるようです。

-[[Docking control with tear-away frame tool windows: By Iridar>http://www.codeproject.com/cs/miscctrl/docking_control.asp]]

フォームデザイナでフォームに貼り付け、デザインできます。機能は少なく、バグも多いようです。

-[[Docking Control: By rovshan876>http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=c0e032b6-96a2-4416-9004-bbd1cd6f1fe1]]

「This is a docking control like in IDE.」とのことです。

-[[divil.co.uk - Docking Suite>http://www.divil.co.uk/net/controls/dockingsuite/]]

非商用での使用のみ無料で使用できるようです。

有料のものを含め、「Windows Forms」でもいくつか紹介されています。

-[[Windows Forms : Control Gallery - Docking Windows>http://www.windowsforms.net/ControlGallery/default.aspx?Category=7&tabindex=9]]

なお、ここで紹介されていないものをご存知の方は、ぜひご連絡ください。よろしくお願いいたします。

**.NET質問箱 [#l7480633]

***VarPtr, StrPtr, ObjPtr関数の代わりになるものは? [#w79e5a33]

#column(注意){{
この記事の最新版は「[[VarPtr, StrPtr, ObjPtr関数の代わりになるものは?>http://dobon.net/vb/dotnet/vb6/objptr.html]]」で公開しています。
}}

''質問:''

Visual Basic 6.0のVarPtr, StrPtr, ObjPtr関数がVB.NETではなくなりましたが、何か換わりになるものはないでしょうか?

''答え:''

VB6のVarPtr, StrPtr, ObjPtr関数は変数の下位のメモリアドレスを取得するためのドキュメント化されていない関数です。「Visual Basic .NET へのアップグレードを円滑に行うための Visual Basic 6.0 アプリケーションの準備」や「VB 6.0 ユーザーのための VB .NET 移行ガイド - レガシー機能」によると、これらの関数はVB.NETではサポートされていないとのことです。

-[[Visual Basic .NET へのアップグレードを円滑に行うための Visual Basic 6.0 アプリケーションの準備>http://www.microsoft.com/japan/msdn/vs/vb6/vb6tovbdotnet.asp]]
-[[VB 6.0 ユーザーのための VB .NET 移行ガイド - レガシー機能>http://www.microsoft.com/japan/msdn/net/vbtransitionguide/chapter4/chapter4_16.asp]]

.NETではこれらの機能が必要になる機会はそうはないでしょうが、.NETでもオブジェクトのアドレスを取得することは可能です。しかしこのとき問題になるのは、アドレスを取得し、それを使用する間、共通言語ライブラリ(CLR)によってこのアドレスが変更されないことを確実にしなければならないということです。共通言語ライブラリはガベージコレクタによって、効率化のためにオブジェクトをメモリ内で移動しているのです。

そのため、オブジェクトのアドレスはGCHandle.AddrOfPinnedObjectメソッドで取得し、このときに必要なハンドルはGCHandle.Allocメソッドで取得します。使い終わった後はGCHandle.Freeメソッドによりハンドルを解放します。

次のサンプルは、オブジェクト"obj"のアドレスを取得するものです。

#code(csharp){{
//using System.Runtime.InteropServices;
//が宣言されているものとする

//ガベージコレクタがオブジェクトを移動できないようにする
GCHandle gch = GCHandle.Alloc(obj, GCHandleType.Pinned);
//固定オブジェクトのアドレスを取得する
int address = gch.AddrOfPinnedObject().ToInt32();

//ハンドルを解放する
//オブジェクトの移動ができるようになる
gch.Free();
}}

#code(vbnet){{
'Imports System.Runtime.InteropServices
'が宣言されているものとする

'ガベージコレクタがオブジェクトを移動できないようにする
Dim gch As GCHandle = GCHandle.Alloc(obj, GCHandleType.Pinned)
'固定オブジェクトのアドレスを取得する
Dim address As Integer = gch.AddrOfPinnedObject().ToInt32()

'ハンドルを解放する
'オブジェクトの移動ができるようになる
gch.Free()
}}

参考:

-[[developer.com - The Book of VB .NET: Migrating to Visual Basic .NET, Part 2 (By Matthew MacDonald)>http://www.developer.com/tech/article.php/1007901]]

掲示板過去ログ:
http://dobon.net/vb/bbs/log3-1/50.html

***DataGridコントロールのセル内でのキーイベントを補足するには? [#m7a19f04]

#column(注意){{
この記事の最新版は「[[DataGridのセル内でのキーイベントを捕捉する>http://dobon.net/vb/dotnet/datagrid/catchkeyevents.html]]」で公開しています。
}}

''質問:''

DataGridコントロール(System.Windows.Forms)のセル内でキーをたたいた時のKeyDownイベントを捕捉したいのですが、DataGridのKeyDownイベントでは認識してくれません。どのようにすればよいのでしょうか?

''答え:''

DataGridコントロールのKeyDownイベントではなく、セルのTextBoxのKeyDownイベントを捕捉するようにします。セルのTextBoxオブジェクトは列スタイルDataGridTextBoxColumnのTextBoxプロパティから取得できます。

次の例では、DataGridコントロールDataGrid1にテーブルスタイル"DataTable1"が設定されているものとし、その1列目のセルでのKeyDownイベントを捕捉しています。

#code(csharp){{
//フォームのLoadイベントハンドラ
private void Form1_Load(object sender, System.EventArgs e)
{
	//DataGrid1にはテーブルスタイル"DataTable1"が
	//設定されているものとする
	
	//テーブルスタイルの取得
	DataGridTableStyle ts;
	ts = DataGrid1.TableStyles["DataTable1"];

	//DataGridTextBoxColumnの取得
	DataGridTextBoxColumn cs =
		(DataGridTextBoxColumn) ts.GridColumnStyles[0];
	
	//TextBoxの取得
	TextBox tb = cs.TextBox;
	//KeyDownイベントハンドラを追加
	tb.KeyDown += new KeyEventHandler(tb_KeyDown);
}

//KeyDownイベントハンドラ
private void tb_KeyDown(object sender, KeyEventArgs e)
{
    //押されたキーを表示
	Console.WriteLine("キー({0})が押されました。", e.KeyCode);
}
}}

#code(vbnet){{
'フォームのLoadイベントハンドラ
Private Sub Form1_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load
    'DataGrid1にはテーブルスタイル"DataTable1"が
    '設定されているものとする
    'テーブルスタイルの取得
    Dim ts As DataGridTableStyle
    ts = DataGrid1.TableStyles("DataTable1")

    'DataGridTextBoxColumnの取得
    Dim cs As DataGridTextBoxColumn = _
        CType(ts.GridColumnStyles(0), DataGridTextBoxColumn)

    'TextBoxの取得
    Dim tb As TextBox = cs.TextBox
    'KeyDownイベントハンドラを追加
    AddHandler tb.KeyDown, AddressOf tb_KeyDown
End Sub

'KeyDownイベントハンドラ
Private Sub tb_KeyDown(ByVal sender As Object, _
        ByVal e As KeyEventArgs)
    '押されたキーを表示
    Console.WriteLine("キー({0})が押されました。", e.KeyCode)
End Sub
}}

掲示板過去ログ:
http://dobon.net/vb/bbs/log3-1/31.html

***DataGridコントロールのAllowSortingプロパティをFalseにしても並べ替えができてしまう [#u7df9155]

#column(注意){{
この記事の最新版は「[[DataGridのAllowSortingプロパティをFalseにしても並べ替えができてしまう問題の解決法>http://dobon.net/vb/dotnet/datagrid/allowsorting.html]]」で公開しています。
}}

''質問:''

DataGridコントロール(System.Windows.Forms)のAllowSortingプロパティをFalseにしても、列カラムをクリックすると並び替えされてしまいます。なぜでしょうか?

''答え:''

DataGridコントロールにテーブルスタイルが設定されていないか確かめてください。DataGridコントロールにテーブルスタイルが設定されている時、並び替えの許可、不許可はDataGridコントロールのAllowSortingプロパティで設定するのではなく、使用しているDataGridTableStyleのAllowSortingプロパティで設定する必要があります。

よってDataGridコントロールにテーブルスタイルが設定されているときは、設定されているDataGridTableStyleのAllowSortingプロパティをFlaseにします。ほとんどの場合、これで解決できるでしょう。

次の例では、DataGridコントロールDataGrid1にテーブルスタイル"DataTable1"が設定されている時に、列ヘッダのクリックで並び替えをできないようにしています。

#code(csharp){{
//DataGrid1にはテーブルスタイル"DataTable1"が
//設定されているものとする

//テーブルスタイルの取得
DataGridTableStyle ts;
ts = DataGrid1.TableStyles["DataTable1"];

//並び替えできないようにする
ts.AllowSorting = false;
}}

#code(vbnet){{
'DataGrid1にはテーブルスタイル"DataTable1"が
'設定されているものとする

'テーブルスタイルの取得
Dim ts As DataGridTableStyle
ts = DataGrid1.TableStyles("DataTable1")

'並び替えできないようにする
ts.AllowSorting = False
}}

掲示板過去ログ:
http://dobon.net/vb/bbs/log3-1/157.html

**コメント [#hdc788fe]
#comment

//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2004-02-23 (月) 06:00:00,DOBON!,2010-03-21 (日) 01:45:13,DOBON!)
[ トップ ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]