SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ComponentZine(ComponentOne)

WPFアプリケーションにテキストブロックのプロパティ変更機能を実装する

ComponentOne Studioを活用したWindowsフォームアプリケーションの作成

  • X ポスト
  • このエントリーをはてなブックマークに追加

 「ComponentOne Studio 2013J」に含まれるPropertyGrid for WPFのC1PropertyGridコントロールを使って、テキストブロックの背景色、文字、文字色を変更できる機能を、WPFアプリケーションに実装してみます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 前回『WPFアプリケーションにカラーピッカーを実装する』で作成したWPFアプリケーションでは、TextBlockコントロールの背景色をカラーピッカーで変更できるようにしました。しかし、どうせなら文字や文字色も一緒に変更できたら便利ですね。でも、そうなると専用のダイアログボックスが必要になります。

 ダイアログボックスを使うとなると、データの受け渡し処理などを組み込まなくてはならず、手のかかる改修作業になってしまいます。

 もっと簡単にできる方法はないかと探していたら、PropertyGrid for WPFのC1PropertyGridコントロールを見つけました。

 このコントロールを使用すると、アプリケーション実行時にウィンドウに配置したオブジェクトのプロパティを参照したり編集したりすることが可能となります。そして、操作できるプロパティも自由にセレクトでき、必要なプロパティのみ編集操作ができる、という大変優れたコントロールです。

 更に、このコントロールを使えば、ダイアログボックスの作成やデータの受け渡し処理は不要になります。

 そこで今回は、カラーピッカーに代わりこのC1PropertyGridコントロールを使用して、テキストブロックの背景色、文字、文字色を変更できる機能を実装してみました。

テキストブロックを右ボタンでクリックすると、3つのプロパティが操作できる
テキストブロックを右ボタンでクリックすると、3つのプロパティが操作できる
背景色、氏名、文字色の編集が可能
背景色、氏名、文字色の編集が可能

対象読者

 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」コントロールです。

アセンブリ名が「C1.WPF.Extended.4」の「C1PropertyGrid」コントロールを選択する
アセンブリ名が「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のプロパティウィンドウとよく似た操作性を提供します。たとえば、色を設定するプロパティではカラーピッカーが表示され、文字情報を操作するプロパティでは直接文字列の入力が可能で、数値データは数値入力ボタンが表示されるなど、プロパティウィンドウの値入力と同じインターフェイスがそのままユーザーに提供されます。

TextBlockコントロールのプロパティ一覧が表示されている
TextBlockコントロールのプロパティ一覧が表示されている
プロパティウィンドウと同じインターフェイスでプロパティ設定が行える
プロパティウィンドウと同じインターフェイスでプロパティ設定が行える

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つ追加します。

PropertyAttributeオブジェクトを1つ追加する
PropertyAttributeオブジェクトを1つ追加する

 ⑥ 右ペインの「その他」をクリックして展開し、次のプロパティを設定します。

DisplayName MemberName
背景色 Background
2つのプロパティを設定する
2つのプロパティを設定する

 ⑦ あと2回「追加」ボタンをクリックし、PropertyAttributeオブジェクトを2つ追加します。

 そして、次のプロパティを設定します。

DisplayName MemberName
文字色 Foreground
氏 名 Text

 ⑧ アプリケーションを実行してみます。設定した3つのプロパティが表示されていればOKです。

設定した3つのプロパティが表示されていればOK
設定した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プロパティ内の空白

 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プロパティを切り替えます。

Visual Basic
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
C#
 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コントロールは、このようにウィンドウにレイアウトされたコントロールを、アプリケーション実行時に操作することができるコントロールです。

 面倒なダイアログボックス作成・処理なども必要なく、各コントロールへの連結やプロパティリスト作成など、とても簡単にこの機能を実装することが可能です。

 インタラクティブなアプリケーションに仕上げたいという場合は、導入を検討されてはいかがでしょうか。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7594 2014/01/27 18:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング