misc.log

日常茶飯事とお仕事と

XAMLでのバインディング

エッセンシャルWPFのサンプルを追いかけ中。XAMLで書いたチェックボックスの文字列に、別のテキストボックスの入力内容をバインドしてみようとして、以下のような記述をしてみた...。

<TextBox x:Name='SampleText'>テキストボックス(編集可能)</TextBox>
<CheckBox Content='{Binding ElementName=SampleText,Path=Text}'>チェックボックス</CheckBox>

で、MSBuildでビルドしてみると

"C:\Temp\WPFTest1\tour.csproj" (既定のターゲット) (1) -> (MarkupCompilePass1 ターゲット) ->
  C:\Temp\WPFTest1\MyWindow.xaml(24,76): error MC3024: 'System.Windows.Controls.CheckBox.Content' プロパティは既に設定されています。設定できるのは一度だけです。 行 24 位置 76.

なんてエラー。何がまずいかというと、すでに「チェックボックス」という文字が入っていることが「1度目のバインド」にあたるみたい。文字列の設定であっても、内部処理ではリソースへのバインドという扱いになってるのね。

<TextBox x:Name='SampleText'>テキストボックス(編集可能)</TextBox>
<CheckBox Content='{Binding ElementName=SampleText,Path=Text}' />

上記のように、初期文字列を無しにしてやれば問題無かった。

手書きXAMLでサンプル

エッセンシャルWPF(asin:4798114200)を見ながら、とりあえずやってみるテスト。MSBuildも使ったこと無かったので、まずは手書きXAMLMSBuildでビルドしてアプリを動かしてみる実験。ホント基礎の基礎だね。用意するものは

  • アプリケーション定義を書いたapp.xamlファイル
  • ウィンドウ定義を書いたMyWindow.xamlファイル
  • 上記2ファイルをインクルードしてビルドするMSBuild用ファイル

すっかりぬるいVisual Basicの世界で暮らして長いので、MSBuild用の定義とか、大文字小文字間違いとかで何度もエラーを出しながら、ビルド。動かす。で、フォーム一杯に広がったボタンだけのアホみたいなWPFアプリケーション作成稼働風景が右の画像。

ちなみに、Visual Studioしか使ってない人が多分陥るであろうポイントとして、テキストファイル手書きでソースをコンパイラに渡す場合、ファイルはUTF-8とかでエンコードしておかないとコケます。その点忘れないように。

■app.xaml
<Application
	xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
	StartupUri='MyWindow.xaml'
	/>
■MyWindow.xaml
<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' Title='Hello World'>

	<Button>こんにちは</Button>

</Window>
■tour.build
<Project
	DefaultTargets='Build'
	xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>

	<PropertyGroup>
		<Configuration>Debug</Configuration>
		<Platform>AnyCPU</Platform>
		<RootNamespace>Tour</RootNamespace>
		<AssemblyName>Tour</AssemblyName>
		<OutputType>winexe</OutputType>
		<OutputPath>.\bin\Debug\</OutputPath>
	</PropertyGroup>

	<ItemGroup>
		<Reference Include='System' />
		<Reference Include='WindowsBase' />
		<Reference Include='PresentationCore' />
		<Reference Include='PresentationFramework' />
	</ItemGroup>

	<ItemGroup>
		<Page Include='MyWindow.xaml' />
		<ApplicationDefinition Include='app.xaml' />
	</ItemGroup>

	<Import Project='$(MSBuildBinPath)\Microsoft.CSharp.targets' />
	<Import Project='$(MSBuildBinPath)\Microsoft.WinFX.targets' />

</Project>

エッセンシャルWPF:Windows Presentation Foundation (Programmer's SELECTION)

エッセンシャルWPF:Windows Presentation Foundation (Programmer's SELECTION)

拡張プロバイダ

備忘録ですのでよろしく。
http://d.hatena.ne.jp/frontline/20080813/p3 に書いていた添付プロパティのような機能を実現する機能を「拡張プロバイダ」と言うらしい。これを使うには

  1. ProvidePropertyAttribute 属性を使用して、拡張プロバイダから提供されるプロパティを指定する。
  2. 提供されたプロパティを実装する。
  3. 提供されたプロパティをどのコントロールが受け取るかを追跡する。
  4. IExtenderProvider インターフェイスを実装する。

といった手順が必要...ってコレじゃわかんないですよ。後日やってみようかと。MSDNさん曰く、これで追加されたプロパティは、デザイン画面のプロパティグリッド(Visual Studio上でプロパティを一覧表示/設定する小さいグリッド?)には出るけれど、ロジック中でアクセスするには追加された側のコントロール経由ではアクセスできないようで...たとえば、フォームにToolTipTextを用意すると、TextBoxのプロパティ一覧にはToolTipTextプロパティが出てくるけれど、コード中で「TextBox1.ToolTipText」なんてことはできないみたい。