Windows Embedded Compact 7 における Silverlight ページ遷移の実装手法

Windows Embedded Compact 7(WinCE7)環境下で Silverlight for Windows Embedded を用いた UI 開発を行う場合、ページ間の動的切り替えは標準的なナビゲーション機構を備えておらず、独自のコンポジション制御が必要となる。本稿では、XAML ベースのユーザーコントロールを動的にロード・置換するアプローチを、C++ 実装を中心に解説する。

基本設計思想は「ルートコンテナとして機能する Grid を保持し、その子要素コレクションに異なるページクラスのインスタンスを差し替える」ことにある。この方式により、アプリケーション全体の視覚的階層を一貫して管理しつつ、各ページのライフサイクルを明示的に制御可能となる。

1. ルートページの XAML 構造(MainPage.xaml)

以下は最小限のレイアウト構成であり、Gird_Layer_Source という名前の空の Grid を、ページ遷移の挿入ポイントとして定義している。

<UserControl
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="EmbeddedUI.MainPage"
  Width="800" Height="480">

  <Grid x:Name="LayoutRoot" Background="#000">
    <Grid x:Name="Gird_Layer_Source" />
  </Grid>
</UserControl>

2. メインページの初期化(MainPage.cpp)

必要な名前付き要素(LayoutRoot および Gird_Layer_Source)を取得し、後続の動的描画処理に備える。

HRESULT MainPage::InitializeComponent()
{
  HRESULT hr = E_FAIL;
  
  FindName(L"LayoutRoot", &m_pLayoutRoot);
  FindName(L"Gird_Layer_Source", &m_pGird_Layer_Source);

  if (m_pLayoutRoot && m_pGird_Layer_Source)
  {
    hr = S_OK;
  }

  return hr;
}

3. ページクラスの登録(App.cpp)

Silverlight for Windows Embedded では、すべてのカスタムコントロールが事前にアプリケーションに登録される必要がある。以下は MainPageSecondPage の登録処理例である。

HRESULT App::RegisterUserControls()
{
  static PFN_XRCUC_REGISTER s_pfnRegistrations[] =
  {
    &MainPage::Register,
    &SecondPage::Register
  };

  HRESULT hr = S_OK;
  for (size_t i = 0; i < _countof(s_pfnRegistrations) && SUCCEEDED(hr); ++i)
  {
    hr = s_pfnRegistrations[i]();
  }
  return hr;
}

4. ページ遷移の制御ロジック(App.cpp)

アプリケーション起動時に、MainPage の子グリッド参照をグローバル変数 gpMainLayer に保持し、その後任意のタイミングで他のページを動的に追加・置換する。

// グローバル参照(ヘッダで宣言)
IXRGridPtr gpMainLayer = NULL;

// CreateHost 内で初期化
HRESULT App::CreateHost(XRWindowCreateParams* pCreateParams)
{
  XRPtr<IXRCustomUserControl> pControl;
  HRESULT hr = m_pApplication->CreateObject(__uuidof(MainPage), &pControl);
  if (SUCCEEDED(hr))
  {
    hr = m_pApplication->CreateHostFromElementTree(pControl, pCreateParams, &m_pVisualHost);
    
    // MainPage の子グリッドをキャプチャ
    IXRCustomUserControl* pBase = static_cast<IXRCustomUserControl*>(pControl);
    MainPage* pMain = dynamic_cast<MainPage*>(pBase);
    if (pMain && pMain->m_pGird_Layer_Source)
    {
      gpMainLayer = pMain->m_pGird_Layer_Source;
    }
  }
  return hr;
}

// OnStartup で遷移実行(例:起動直後に SecondPage を表示)
HRESULT App::OnStartup()
{
  if (gpMainLayer)
  {
    IXRUIElementCollection* pChildren = nullptr;
    gpMainLayer->GetChildren(&pChildren);
    if (pChildren)
    {
      XRPtr<SecondPage> pTarget;
      HRESULT hr = m_pApplication->CreateObject(__uuidof(SecondPage), &pTarget);
      if (SUCCEEDED(hr) && pTarget)
      {
        pChildren->Clear(); // 既存コンテンツをクリア(オプション)
        pChildren->Add(pTarget, nullptr);
      }
      pChildren->Release();
    }
  }
  return S_OK;
}

5. 遷移先ページの定義(SecondPage.xaml)

独立した XAML リソースとして定義され、Background やボタン配置など、独自のビジュアル構成を持つ。

<UserControl
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="EmbeddedUI.SecondPage"
  Width="800" Height="480">

  <Grid x:Name="LayoutRoot" Background="Green">
    <Button Content="Second Page" Width="177" Height="38" Margin="65,54,0,0" />
    <Button Content="Back to Main" Width="177" Height="38" Margin="65,117,0,0" />
  </Grid>
</UserControl>

タグ: Silverlight-for-Windows-Embedded Windows-Embedded-Compact-7 C++ XAML UI-composition

6月3日 22:08 投稿