2011年9月30日金曜日

◆詳細画面にリンクする

データ項目をリンクラベルで表示して詳細画面を表示してみる。

サンプルは前回のものを使用する。

    1. 「ソリューションエクスプローラー」にて「顧客注文一覧」画面をダブルクリックしてデザイナー画面を表示させる。
    2. コントロールツリーにて「Orders Item」の中の「Order ID」を選択し「プロパティウィンドウ」にて「リンクとして表示」をチェックする。
      image
    3. これで実行すると以下のような画面が表示されて、「Order ID」をクリックすると詳細画面が表示される。
      ちなみに、この詳細画面は特に自分で作らなくても自動生成されるようだ。
      2011-09-30 16h07_222011-09-30 16h07_49

 

次に、ここで表示される詳細画面はデザイナーから簡単にカスタマイズできるものではなさそうなので、独自の詳細画面を作り差し替えてみる。

    1. 「ソリューションエクスプローラー」にて「画面」フォルダを右クリックして表示されたメニューから「画面の追加」をクリックする。
      image
    2. 「新しい画面の追加」ダイアログにて以下のように設定して「OK」ボタンをクリックする。
      image
    3. 画面が差し替わったのが分かるようにプロパティを一つ追加する。
      ツールバーの「データ項目の追加」をクリックし以下のローカルプロパティを追加する。
      image
    4. 追加された「タイトル」を画面ツリーにドラッグ。
      image
    5. 「プロパティ」ウインドウで表示名を「注文詳細」に変更。
      image
    6. 「プロパティ」画面にて「読取り専用コントロールの使用」をチェックしておく。(特に深い意味は無いが)
      image
    7. これで実行すると以下のような画面が表示されて「Order ID」のリンクをクリックすると差し替えた詳細画面が表示される。
      読み取り専用に変えたためラインが何も表示されず雑然とした感が強いが、ココらへんを調整する術がGUI上からは見当たらない。
      全般的に見栄えを変更する機能には力が入れられていない気がする。
      image
    8. ここで、詳細画面を作っただけで自動的に表示画面が差し替えられるのは、手順2にて「規定の詳細画面として使用」にチェックが入っているためだと思う。
      明示的に切り替えるには「顧客別注文一覧」の画面ツリーにて「Order ID」のプロパティ「ターゲット画面」に「注文詳細」を指定すれば良い。
      image

◆ボタンの有効無効を制御する

状況に応じてボタンを非活性にする方法をメモしておく。

サンプルは前回のものを使用する。

注文の件数が4件を超える顧客には新規の注文を制限してみる。

    1. 「ソリューションエクスプローラー」にて「顧客注文一覧」画面をダブルクリックしてデザイナー画面を表示する。
      image
    2. 「Orders By Ship Via1」データグリッドの「追加」ボタンを右クリックして表示されたメニューから「CanExecuteコードの編集」をクリックする。
      image
    3. 表示されたソース画面にて以下のコーディングを追加する。
              partial void OrdersByShipVia1AddAndEditNew_CanExecute(ref bool result)
      {
      // Write your code here.
      if (OrdersByShipVia1.Count > 4) { result = false; }

      }

    4. これを実行して4件以上の注文がある顧客を選択すると「追加」ボタンが非活性になる。
      image

◆クエリーとのデータ連結

LightSwitchではテーブル同士の(というかEntity同士)のリレーションは、データソースのテーブルに外部キーが設定してあれば自動的に張られる。

そのデータソースを基にすれば、簡単にテーブル同士が連携した画面を作ることが出来る。
しかし、実アプリケーションでは単純にテーブルの全データを使うのではなく、ある条件で絞り込んだ上で使用することが多い。(例えば、削除フラグが立っているデータは除くとか)

Accessとかであればテーブルとクエリを連結したり、クエリ同士を連結したりということがGUIで簡単にできる。

LightSwitchでこれを実現するにはいくぶん直感的でない作業が必要になるので、その方法を纏めておく。

<データ>

まずはいつもどおりNorthwindから以下のテーブルを追加してデータソースを作る。

  • Customers
  • Employees
  • Orders
  • Order_Details

2011-09-30 11h51_40

<画面>

テンプレートに「一覧および詳細画面」を指定して画面を作成。
image

実行すると以下のような画面が表示される。
2011-09-30 13h12_54

 

ここで、現在グリッド表示部分は「Orders」テーブルからそのまま表示されているが、これをクエリにしてみる。

<クエリ>

デザイン画面に戻って、左ペインの「Orders」から「クエ入りの編集」リンクをクリックする。
image

表示された「クエリデザイナ」画面にてフィルタを追加する。
ここでは便宜的に以下のフィルタを追加した。
image

これで実行すると以下のように「Ship Via」が「1」で絞りこまれた注文一覧が表示される。
image

これだけで良ければ直感的かつ簡単で良いのだが(実際これでも良いだろう)、ここで使用したクエリは画面レベルのクエリで、他の画面などでは使用できないし、フィルタが追加されていることがデザイン画面では容易に把握できないためある程度の規模になってくると見通しを悪くする可能性がありそうだ。

そこで、これをアプリケーション全体をスコープとするクエリに作り替えてみる。

  1. まずは今作ったフィルタを削除する。
  2. 「ソリューションエクスプローラー」の「Orders」テーブルを右クリックして表示されたメニューから「クエリの追加」を選択する。
    image
  3. クエリの名前を「OrdersByShipVia1」と指定し、先ほどと同じフィルタを追加する。
    2011-09-30 13h38_31
  4. 「ソリューションエクスプローラー」にて「顧客別注文一覧」画面をダブルクリックしてデザイナー画面を表示させる。
  5. デザイナー画面、左ペインの「Orders」を右クリックして表示されたメニューから「削除」をクリックする。
    image
  6. デザイナー画面上部のツールバーにて「データ項目の追加」をクリックし表示された「データ項目の追加」画面にて「OrdersByShipVia1」クエリを選択しOKをクリックする。
    image
  7. 左ペインに追加された「OrdersByShipVia1」を画面ツリーの「Details Column」の下にドラッグして追加する。
    image
  8. これで一旦表示してみると以下のような画面が表示される。
    2011-09-30 13h51_36
  9. 「Ship Via」は1のデータが表示されているが、顧客を選択しなおしても「Orders」のデータが変わらないのが分かる。
    「Customers」と「OrdersByShipVia1」の関連ができていないのである。
    ココらへんがもう少し簡単になれば良いと思うのだが、とりあえず以下のような手順になりそうだ。
  10. 「ソリューションエクスプローラー」にて「OrdersByShipVia1」をダブルクリックしてデザイナー画面を開く。
  11. 表示されたデザイナー画面にてフィルターを以下のように追加編集する。
    (CutsomerIDを使ったパラメータクエリにする)
    image
  12. 「ソリューションエクスプローラー」にて「顧客別注文一覧」をダブルクリックして表示されたデザイン画面の左ペインにて「OrdersShipVia1」の「CustomerID」パラメータを選択する。
    image
  13. 「プロパティ」ウインドウにて「パラメータバインド」をクリックし、表示されたメニューで「Customers」を選択。
    ピリオドを入力し「SelectedItem」を選択。
    ピリオドを入力し「CustomerID」を選択。
    imageimageimage
    これで左ペインを見ると「CustomerID」に矢印が引かれ、連結されたことが分かる。
    image
  14. 以上を実行すると画面は以下のようになる。
    2011-09-30 14h12_35
    こんどは「Customers」の選択に応じて「Orders」の表示が変わるのが分かる。
  15. 最後にレイアウトが今ひとつなので、これを調整する。
    ちなみに、今のレイアウトは以下の状態に成っている。
    2011-09-30 14h15_17
    これは、ルートノード「顧客別注文一覧」の下に4つのノードがあることを表している。
    また、ルートノードは「列のレイアウト」となっているので、子どもの4つのノードは横並びになる。(HorizontalAlighが指定されたStackパネルが使われていると思われる)
  16. データグリッドを以下のようにドラッグし、「Details Column」の子ノードにする。
    image
  17. 以上で実行すると初期表示と同様のレイアウトで表示される。
    2011-09-30 14h25_33

2011年9月28日水曜日

◆カスタムコントロールを使う

LightSwitchでは標準ではテキストボックス、ラベル、オートコンプリートボックスなどコントロールにあまり選択肢がない。

そのかわり、カスタムコントロールというのが用意されていて、その実体はSilverlightのコントロールなどを選択して自由に使えるようだ。(当然自作もできたりする)

そこで簡単な画面を作ってカスタムコントロールの使い方を確認してみる。

<データソース>

以下のようなテーブルをSQLExpressに作って使用する。
2011-09-28 18h00_10

    1. 「ソリューションエクスプローラー」の「データソース」フォルダを右クリックして表示されたメニューから「データソースの追加」をクリックする。
      image
    2. 上記テーブルを作ったデータベースを指定してOK
      image
    3. テーブルを選択して「完了」
      image
      2011-09-28 18h07_04

<画面>

    1. 「ソリューションエクスプローラー」で「画面」フォルダを右クリックして「画面の追加」を選択する。
      image
    2. 画面テンプレートに「新規データ画面」、画面データに「UsersItem」を指定してOK
      image
    3. 表示されたコントロールツリーにて「Password」のドロップダウンを展開し「カスタムコントロール」を選択する。
      image
    4. 「プロパティウインドウ」にて「カスタムコントロール」の「Change」リンクをクリックする。
      image
    5. 以下のネームスペースから「PasswordBox」を選択してOK
      image

      これでOKなら、簡単簡単となるところなのだが、どうもこれだけではダメなようである。
      「UserItemProperty.Password」に「PasswordBox」が関連づくところまではできているのだが、「PasswordBox」の何のプロパティを使うかが指定できていない。
      「PasswordBox」のプロパティ一覧を表示して選択させるくらいのことはGUIで簡単にできそうなものなのだが、そうはなっていないようである。
      そこで、以下の作業を追加してプロパティを指定してあげる。
    6. デザイナー画面上部のツールバーから「コードの記述」をクリックし、表示されたメニューから「CreateNewUsersItem_Created」を選択する。
      image

<コーディング>

    1. 表示されたソース画面で以下のようにコーディングする。
              partial void CreateNewUsersItem_Created()
      {
      // ここにコードを書き込んでください。
      this.FindControl("Password").SetBinding(
      System.Windows.Controls.PasswordBox.PasswordProperty,
      "Value", System.Windows.Data.BindingMode.TwoWay);

      }

      <追記>ここだと毎回バインディング処理が走って無駄なのでInitializeDataWorkSpaceとかのほうが良さそう。
    2. これで実行すると以下のような画面が表示されマスクされたパスワードで登録することができる。
      2011-09-28 23h24_00

      のだが、登録後の画面を見て思わず笑ってしまう。
      2011-09-28 23h25_26

      ん~、これでは苦労が水の泡。なんでこんなことになってしまうのか・・・。
      ソースを見てみると「保存」コマンドに以下のようなコードが自動生成されている。


              partial void CreateNewUsersItem_Saved()
      {
      // ここにコードを書き込んでください。
      this.Close(false);
      Application.Current.ShowDefaultScreen(this.UsersItemProperty);
      }


      DefaultScreenってやつはカスタマイズとは無関係なのね・・・。


    3. 登録後にどんな画面にするかは仕様次第だと思うが、とりあえず連続登録できるように初期画面表示と同じように書き換えてみた。


              partial void CreateNewUsersItem_Saved()
      {
      // ここにコードを書き込んでください。
      //this.Close(false);
      //Application.Current.ShowDefaultScreen(this.UsersItemProperty);
      this.UsersItemProperty = new UsersItem();
      this.FindControl("UserName").Focus();
      }


以上で、とりあえずサンプルとしてはOKっぽい。
画面コントロールの参照が文字列参照になってしまうのが気に入らないが、今のところ他の参照方法も見当たらなかったので良しとする。

2011年9月26日月曜日

◆検索条件+検索結果グリッドの画面を作る2

前回作成した検索画面は検索条件の「CategoryID」に直接値を入力したが、通常のアプリケーションではこういった値は選択肢の一覧から選んで入力するのが一般的だ。

そこで検索条件に修正を加えて「Category」の一覧を表示させてみる。

    1. 「ソリューションエクスプローラー」で「EditableProductByCategoryGrid」画面をダブルクリックしてデザイナー画面を表示させる。
    2. 左ペインに現在使用しているローカルプロパティ「ProductsItemCategoryID」が表示されているのでこれを削除。(DELキー、もしくはコンテキストメニュー)
      image
      ちなみに、このパラメータを削除すると画面ツリーから連結コントロールも削除される。
      image
    3. 代わりのパラメータを定義するため、デザイナ画面上部のツールバーから「データ項目の追加」をクリックする。
      image
    4. 「CategoriesItem」のローカルプロパティを追加する。(名前を「カテゴリー」とする)
      image
    5. デザイン画面に戻ると「カテゴリー」が追加されている。
      2011-09-26 18h41_31
    6. 後は、「クエリーパラメータ」の「CategoryID」に、追加した「カテゴリー」の「CategoryID」を結びつけてあげればOK
      ・「CategoryID」を選択
      ・「プロパティ」ウインドウの「パラメータバインド」欄をクリック
      ・「カテゴリー」を選択
      image
      ・「カテゴリー」の後ろに「.」ピリオドを入力すると選択肢に「CategoryID」が表示されるのでこれを選択。
      image
      結果としてこうなる。
      2011-09-26 18h50_09
    7. 最後に、「カテゴリー」を表示するコントロールを画面に追加する。
      ・ルート項目を選択して、表示された「追加」ボタンをクリックし、「カテゴリー」を追加する。
      image
      ・追加された「カテゴリー」を「画面コマンドバー」の下まで移動させる。
      image
    8. これを実行すると以下のような画面が表示され、「カテゴリー」の選択に応じて該当する「Product」がグリッドに表示されるようになる。
      2011-09-26 19h06_54