はじめに
前回『WPFアプリケーションにカラーピッカーを実装する』で作成したWPFアプリケーションでは、TextBlockコントロールの背景色をカラーピッカーで変更できるようにしました。しかし、どうせなら文字や文字色も一緒に変更できたら便利ですね。でも、そうなると専用のダイアログボックスが必要になります。
ダイアログボックスを使うとなると、データの受け渡し処理などを組み込まなくてはならず、手のかかる改修作業になってしまいます。
もっと簡単にできる方法はないかと探していたら、PropertyGrid for WPFのC1PropertyGridコントロールを見つけました。
このコントロールを使用すると、アプリケーション実行時にウィンドウに配置したオブジェクトのプロパティを参照したり編集したりすることが可能となります。そして、操作できるプロパティも自由にセレクトでき、必要なプロパティのみ編集操作ができる、という大変優れたコントロールです。
更に、このコントロールを使えば、ダイアログボックスの作成やデータの受け渡し処理は不要になります。
そこで今回は、カラーピッカーに代わりこのC1PropertyGridコントロールを使用して、テキストブロックの背景色、文字、文字色を変更できる機能を実装してみました。
対象読者
Visual Basic 2010/2012、またはVisual C# 2010/2012を使ってプログラムを作ったことがある人。
必要な環境
Visual Basic 2010/2012、Visual C# 2010/2012、Visual Studio 2010/2012、SQL Server Expressでプログラムが作れる環境。
なお、本プログラムは次の環境で開発・動作確認を行っています。
- OS:Windows 7
- 開発Tool:Visual Studio 2010、.NET Framework 4
プログラム実行時の注意事項
本稿の実行ファイル(バイナリファイル)を動かすには、zipファイルに同梱してある以下のファイルが必要になります(.NET Framework 4でのみご使用いただけます)。
ファイル名 | 説明 |
---|---|
C1.WPF.4.dll | 本体アセンブリ |
C1.WPF.Extended.4.dll | 本体アセンブリ |
このファイルを、実行プログラムと同じフォルダに格納します。
コンポーネントのインストール
トライアル版は、グレープシティのWebページから申し込みできます。
トライアル申込フォームが表示されますので、必要情報を入力して申し込むとトライアル版のダウンロード手順を記載したE-Mailが送られてきます。その手順にそってダウンロードを行ってください。また、ダウンロードファイルは圧縮ファイルになっていますので、解凍してインストーラを起動します。
制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。
コントロールの追加
「ComponentOne Studio 2013J」をインストールしたら、プロジェクトにコントロールを追加します。
ツールボックスに専用のタブを作成し、使用するコンポーネントを追加します。追加するコンポーネントは、アセンブリ名が「C1.WPF.Extended.4」の「C1PropertyGrid」コントロールです。
このコントロールを追加すると、プロジェクトに以下のランタイムライブラリへの参照が追加されます。.NET Framework 4が必要です。
ファイル | 内容 |
---|---|
C1.WPF.4 | 本体アセンブリ |
C1.WPF.Extended | 本体アセンブリ |
C1PropertyGridコントロールの概要 1
PropertyGrid for WPFのC1PropertyGridコントロールは、Windowsプラットフォームに組み込まれた標準のPropertyGridコントロールのWPFバージョンです。
各コントロールと連結することで、アプリケーション実行時にコントロールのプロパティを編集することができます。
また、このコントロールには10種類以上の組み込みエディタが用意されており、操作できるプロパティ項目を自由に選んで組み合わせることができます。
アプリケーション実行時に操作するプロパティはリスト状に表示され、Visual Studioのプロパティウィンドウとよく似た操作性を提供します。たとえば、色を設定するプロパティではカラーピッカーが表示され、文字情報を操作するプロパティでは直接文字列の入力が可能で、数値データは数値入力ボタンが表示されるなど、プロパティウィンドウの値入力と同じインターフェイスがそのままユーザーに提供されます。
C1PropertyGridコントロールの概要 2
プロパティ項目の編集
C1PropertyGridコントロールは、デフォルトでは連結したコントロールのすべてのプロパティを表示する設定になっていますが、この項目を自由にカスタマイズすることができます。
この操作には専用のエディタが用意されており、ここでアプリケーション実行時に操作したいプロパティを選びます。
プロパティ項目をカスタマイズする場合は、まずプロパティウィンドウで「AutoGenerateProperties」プロパティのチェックを外します。次に、「PropertyAttributes」プロパティの値欄にある「...」ボタンをクリックすると、PropertyAttributeオブジェクトを編集するコレクションエディタが起動します。
コレクションエディタでは、「追加」ボタンをクリックしてPropertyAttributeオブジェクトを追加します。このオブジェクト1つが1つのプロパティとなります。
そして、右ペインにある「DisplayName」と「MemberName」プロパティを設定します。「DisplayName」プロパティは表示されるプロパティ名で、「MemberName」プロパティが操作したいプロパティの名称です。たとえば、TextBlockコントロールの背景色を操作したければ、「DisplayName」プロパティに「背景色」と、「MemberName」プロパティには「Background」と入力します。
プロパティをグループでまとめたい場合は、「Category」にグループ名を入力します。
こうして、コントロール一つ一つに対して操作できるプロパティのリストを作成します。
他のコントロールとのバインド
プロパティ操作をしたいコントロールとC1PropertyGridコントロールを連結するには、C1PropertyGridコントロールのSelectedObjectプロパティに、XAMLで次のようにBinding ElementNameを設定します。
SelectedObject="{Binding ElementName=TextBlock3, Mode=OneWay}"
たったこれだけで、C1PropertyGridコントロールはこのオブジェクトからプロパティ一覧を取出しリスト表示してくれます。
GUIの作成 1
ではさっそくアプリケーションに、この機能を組み込んでいきましょう。
前回作成したアプリケーションの、C1ColorPickerコントロールとTextBlockコントロールを削除し、ここにCanvas要素を入れます。
そして、Canvas要素の中に、氏名用TextBlockの数だけC1PropertyGridコントロールを作成し重ねてレイアウトします。
C1PropertyGridコントロールは、TextBlockコントロールのText、Background、Foregroundの3つのプロパティだけを表示し、氏名と背景色、文字色を自由に編集できるようにします。
C1PropertyGridコントロールの作成
まずは、C1PropertyGridコントロールを作成します。
① すでに配置してあるC1ColorPickerコントロールと「背景色」TextBlockコントロールを削除します。
② そのあとにCanvas要素を作成します。Canvas要素は、複数のコントロールを重ねて表示することができるので、C1PropertyGridコントロールを同じ位置で切り替えて表示させることができます。
<Canvas></Canvas>
③ Canvas要素の中にC1PropertyGridコントロールを作成します。
<c1:C1PropertyGrid Name="c1PropertyGrid1" />
④ 名前を付け、高さと幅、SelectedObjectプロパティを設定します。
最初の操作対象TextBlockコントロールは「TextBlock2」です。
<Canvas Name="Canvas1" Margin="0,10,0,0"> <c1:C1PropertyGrid Name="C1PropertyGrid1" Height="74" Width="464" SelectedObject="{Binding ElementName=TextBlock2, Mode=OneWay}" Visibility="Visible" Margin="70,0,0,0" />
⑤ GUIエディタに移ってC1PropertyGridコントロールをクリックします。プロパティウィンドウのAutoGeneratePropertiesプロパティのチェックを外します。
そして、PropertyAttributesプロパティの値欄にある「...」ボタンをクリックし、コレクションエディタを表示します。
⑥ 「追加」ボタンをクリックし、PropertyAttributeオブジェクトを1つ追加します。
⑥ 右ペインの「その他」をクリックして展開し、次のプロパティを設定します。
DisplayName | MemberName |
---|---|
背景色 | Background |
⑦ あと2回「追加」ボタンをクリックし、PropertyAttributeオブジェクトを2つ追加します。
そして、次のプロパティを設定します。
DisplayName | MemberName |
---|---|
文字色 | Foreground |
氏 名 | Text |
⑧ アプリケーションを実行してみます。設定した3つのプロパティが表示されていればOKです。
⑨ XAMLウィンドウで、今作成したC1PropertyGridコントロールのコードをコピー・ペーストし、C1PropertyGridコントロールのNameプロパティとBinding ElementNameのTextBlockコントロールの名前を修正します。
<Canvas> <c1:C1PropertyGrid Name="C1PropertyGrid1" Height="74" Width="464" SelectedObject="{Binding ElementName=TextBlock2, Mode=OneWay}" Visibility="Visible" Margin="70,0,0,0" AutoGenerateProperties="False"> <c1:C1PropertyGrid.PropertyAttributes> <c1:PropertyAttribute Browsable="True" DisplayName="背景色 " MaximumValue="NaN" MemberName="Background" MinimumValue="NaN" /> <c1:PropertyAttribute Browsable="True" DisplayName="文字色 " MaximumValue="NaN" MemberName="Foreground" MinimumValue="NaN" /> <c1:PropertyAttribute Browsable="True" DisplayName="氏 名 " MaximumValue="NaN" MemberName="Text" MinimumValue="NaN" /> </c1:C1PropertyGrid.PropertyAttributes> </c1:C1PropertyGrid> <c1:C1PropertyGrid Name="C1PropertyGrid2" Height="74" Width="464" SelectedObject="{Binding ElementName=TextBlock3, Mode=OneWay}" Visibility="Visible" Margin="70,0,0,0" AutoGenerateProperties="False"> <c1:C1PropertyGrid.PropertyAttributes> <c1:PropertyAttribute Browsable="True" DisplayName="背景色 " MaximumValue="NaN" MemberName="Background" MinimumValue="NaN" /> <c1:PropertyAttribute Browsable="True" DisplayName="文字色 " MaximumValue="NaN" MemberName="Foreground" MinimumValue="NaN" /> <c1:PropertyAttribute Browsable="True" DisplayName="氏 名 " MaximumValue="NaN" MemberName="Text" MinimumValue="NaN" /> </c1:C1PropertyGrid.PropertyAttributes> </c1:C1PropertyGrid> </Canvas>
DisplayNameプロパティは、文字列の後に空白を少し入れておくと、リスト表示時に枠内にスペースを付けて表示されます。
⑩ C1PropertyGridコントロール「C1PropertyGrid2」をクリックし、プロパティウィンドウのVisibilityプロパティを「Hidden」にします。
<c1:C1PropertyGrid Name="C1PropertyGrid2" Height="74" Width="464" SelectedObject="{Binding ElementName=TextBlock3, Mode=OneWay}" Visibility="Hidden" Margin="70,0,0,0" AutoGenerateProperties="False">
⑪ この「C1PropertyGrid2」のコードを4つコピーし、次のようにNameプロパティとBinding ElementNameのTextBlockコントロールの名前を修正します。
Name="C1PropertyGrid3" SelectedObject="{Binding ElementName=TextBlock4, Mode=OneWay}" Name="C1PropertyGrid4" SelectedObject="{Binding ElementName=TextBlock5, Mode=OneWay}" Name="C1PropertyGrid5" SelectedObject="{Binding ElementName=TextBlock6, Mode=OneWay}" Name="C1PropertyGrid6" SelectedObject="{Binding ElementName=TextBlock7, Mode=OneWay}"
これで、6つのC1PropertyGridコントロールが同じ場所に重なって表示されていますが、最初のC1PropertyGridコントロール「C1PropertyGrid1」だけが表示され、あとの5つのC1PropertyGridコントロールは非表示になっています。
GUIの作成 2
C1PropertyGridコントロールの切り替え表示処理
氏名のTextBlockコントロールを右クリックすると、C1PropertyGridコントロールの表示プロパティをそのコントロールのプロパティに切り替える処理を作成します。この処理は、ビハインドコードで行います。
すでに、TextBlockコントロールの右クリックのイベントハンドラは作成されていますので、この中のカラーピッカー処理コードと入れ替えます。処理としては、右クリックされたTextBlockコントロールのNameプロパティを取得し、これによってC1PropertyGridコントロールのVisibilityプロパティを切り替えます。
Private Sub TextBlock_MouseRightButtonDown(sender As System.Object, e As System.Windows.Input.MouseButtonEventArgs) Select Case sender.name Case "TextBlock2" C1PropertyGrid1.Visibility = Windows.Visibility.Visible C1PropertyGrid2.Visibility = Windows.Visibility.Hidden C1PropertyGrid3.Visibility = Windows.Visibility.Hidden C1PropertyGrid4.Visibility = Windows.Visibility.Hidden C1PropertyGrid5.Visibility = Windows.Visibility.Hidden C1PropertyGrid6.Visibility = Windows.Visibility.Hidden Case "TextBlock3" C1PropertyGrid2.Visibility = Windows.Visibility.Visible C1PropertyGrid1.Visibility = Windows.Visibility.Hidden C1PropertyGrid3.Visibility = Windows.Visibility.Hidden C1PropertyGrid4.Visibility = Windows.Visibility.Hidden C1PropertyGrid5.Visibility = Windows.Visibility.Hidden C1PropertyGrid6.Visibility = Windows.Visibility.Hidden Case "TextBlock4" C1PropertyGrid3.Visibility = Windows.Visibility.Visible C1PropertyGrid1.Visibility = Windows.Visibility.Hidden C1PropertyGrid2.Visibility = Windows.Visibility.Hidden C1PropertyGrid4.Visibility = Windows.Visibility.Hidden C1PropertyGrid5.Visibility = Windows.Visibility.Hidden C1PropertyGrid6.Visibility = Windows.Visibility.Hidden Case "TextBlock5" C1PropertyGrid4.Visibility = Windows.Visibility.Visible C1PropertyGrid1.Visibility = Windows.Visibility.Hidden C1PropertyGrid2.Visibility = Windows.Visibility.Hidden C1PropertyGrid3.Visibility = Windows.Visibility.Hidden C1PropertyGrid5.Visibility = Windows.Visibility.Hidden C1PropertyGrid6.Visibility = Windows.Visibility.Hidden Case "TextBlock6" C1PropertyGrid5.Visibility = Windows.Visibility.Visible C1PropertyGrid1.Visibility = Windows.Visibility.Hidden C1PropertyGrid2.Visibility = Windows.Visibility.Hidden C1PropertyGrid3.Visibility = Windows.Visibility.Hidden C1PropertyGrid4.Visibility = Windows.Visibility.Hidden C1PropertyGrid6.Visibility = Windows.Visibility.Hidden Case "TextBlock7" C1PropertyGrid6.Visibility = Windows.Visibility.Visible C1PropertyGrid1.Visibility = Windows.Visibility.Hidden C1PropertyGrid2.Visibility = Windows.Visibility.Hidden C1PropertyGrid3.Visibility = Windows.Visibility.Hidden C1PropertyGrid4.Visibility = Windows.Visibility.Hidden C1PropertyGrid5.Visibility = Windows.Visibility.Hidden End Select End Sub
private void TextBlock_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { TextBlock tb = (TextBlock)sender; switch(tb.Name) { case "TextBlock2": C1PropertyGrid1.Visibility = System.Windows.Visibility.Visible; C1PropertyGrid2.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid3.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid4.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid5.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid6.Visibility = System.Windows.Visibility.Hidden; break; case "TextBlock3": C1PropertyGrid2.Visibility = System.Windows.Visibility.Visible; C1PropertyGrid1.Visibility = System.Windows.Visibility.Visible; C1PropertyGrid3.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid4.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid5.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid6.Visibility = System.Windows.Visibility.Hidden; break; case "TextBlock4": C1PropertyGrid3.Visibility = System.Windows.Visibility.Visible; C1PropertyGrid2.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid1.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid4.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid5.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid6.Visibility = System.Windows.Visibility.Hidden; break; case "TextBlock5": C1PropertyGrid4.Visibility = System.Windows.Visibility.Visible; C1PropertyGrid2.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid3.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid1.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid5.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid6.Visibility = System.Windows.Visibility.Hidden; break; case "TextBlock6": C1PropertyGrid5.Visibility = System.Windows.Visibility.Visible; C1PropertyGrid2.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid3.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid4.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid1.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid6.Visibility = System.Windows.Visibility.Hidden; break; case "TextBlock7": C1PropertyGrid6.Visibility = System.Windows.Visibility.Visible; C1PropertyGrid2.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid3.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid4.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid5.Visibility = System.Windows.Visibility.Hidden; C1PropertyGrid1.Visibility = System.Windows.Visibility.Hidden; break; } }
まとめ
C1PropertyGridコントロールは、このようにウィンドウにレイアウトされたコントロールを、アプリケーション実行時に操作することができるコントロールです。
面倒なダイアログボックス作成・処理なども必要なく、各コントロールへの連結やプロパティリスト作成など、とても簡単にこの機能を実装することが可能です。
インタラクティブなアプリケーションに仕上げたいという場合は、導入を検討されてはいかがでしょうか。