トップ回答者
画面遷移について教えてください。

質問
-
Silverlight、VB2010でアプリケーションを作成しております。
SilverlightのFrameコントロールを使って、以下の動作を行いたく考えております。
①MainPageにFrameを用意して、
Frame1.source = Page1.xaml
を表示させます。Page1.xamlにはボタンコントロール(btn1)があります。
上記状態の際にbtn1を押下したときに、Frame1を画面遷移(Page2.xaml)させたいのですが
うまく遷移させることができません。
基本的な問題で大変申し訳ありませんが、どなたかご教授よろしくお願いいたします。
2011年2月3日 2:32
回答
-
ご指摘の通り、Navigatedイベントは、Frameが切り替わった瞬間に発生するイベントです。
FrameがNavigatedイベントを発行する↓MainPageのFrame1_NavigatedイベントハンドラでPage1のインスタンスを取得する。↓取得したPage1インスタンスのNavigatePage2Requestイベント(このイベントは自分で定義したイベント)にイベントハンドラを登録する。↓Page1のボタンが押されると、NavigatePage2Requestイベントが発行される。↓Page1_NavigatePage2RequestイベントハンドラでPage2に遷移する。という流れになります。長いですが、コードも載せておきます(C#で申し訳ないです)。MainPage.xaml<UserControl x:Class="NavigationSample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <UserControl.Resources> <uriMapper:UriMapper x:Key="uriMapper"> <uriMapper:UriMapping Uri="Page1" MappedUri="/Page1.xaml" /> <uriMapper:UriMapping Uri="Page2" MappedUri="/Page2.xaml" /> </uriMapper:UriMapper> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal" Background="LightCyan"> <HyperlinkButton x:Name="Page1Button" Content="Page1" NavigateUri="Page1" /> <HyperlinkButton x:Name="Page2Button" Content="Page2" NavigateUri="Page2" /> </StackPanel> <navigation:Frame x:Name="Frame" UriMapper="{StaticResource uriMapper}" Grid.Row="1" Background="LightYellow" /> </Grid> </UserControl>
MainPage.xaml.cspublic partial class MainPage : UserControl { public MainPage() { InitializeComponent(); this.Frame.Navigated += new NavigatedEventHandler(this.Frame_Navigated); } private void Frame_Navigated(object sender, NavigationEventArgs e) { var page1 = e.Content as Page1; if (page1 != null) { // 2度イベントハンドラが登録されないように、念のため一度イベントハンドラを抜いてから登録する。 page1.NavigatePage2Request -= new EventHandler(this.Page1_NavigatePage2Request); page1.NavigatePage2Request += new EventHandler(this.Page1_NavigatePage2Request); } } private void Page1_NavigatePage2Request(object sender, EventArgs e) { // Page1のボタンが押されたとき、Page2に遷移する。 this.Frame.Navigate(this.Page2Button.NavigateUri); } }
Page1.xaml<navigation:Page x:Class="NavigationSample.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="Page1 Page"> <Grid x:Name="LayoutRoot"> <Button x:Name="Page2NavigationButton" Content="Page2へ遷移"/> </Grid> </navigation:Page>
Page1.xaml.cspublic partial class Page1 : Page { public Page1() { InitializeComponent(); this.Page2NavigationButton.Click += new RoutedEventHandler(this.Page2NavigationButton_Click); } /// <summary>Page2へ遷移する要求を発行する。</summary> public event EventHandler NavigatePage2Request; private void Page2NavigationButton_Click(object sender, RoutedEventArgs e) { if (this.NavigatePage2Request != null) { this.NavigatePage2Request(this, EventArgs.Empty); } } }
Page2.xaml<navigation:Page x:Class="NavigationSample.Page2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="Page2 Page"> <Grid x:Name="LayoutRoot"> <TextBlock Text="Page2" FontSize="30"/> </Grid> </navigation:Page>
- 回答としてマーク ohzeki 2011年2月3日 20:36
2011年2月3日 13:55
すべての返信
-
こんにちは。
Silverlight デベロッパーセンターにSilverlightのFrameを使用した画面遷移について良い情報が御座いますので参照されてみてはいかがでしょうか?
10行でズバリ!![VB] Silverlight - 画面遷移
とても分かり易く、UriMapperの使用方法もこれで学習できると思います。
是非試してください!
★良い回答には回答済みマークを付けよう! kazuto Blog : http://blogs.wankuma.com/kzt/2011年2月3日 7:44 -
子から親へ処理を依頼する方法はいつも悩まされますね。
子のページ(ここではPage1クラス)にイベントを定義して親ページでそのイベントにイベントハンドラを刺したり、Mediator パターンで子ページから親ページに通知をしたりなどの方法があります。
さらに手っ取り早い方法としましてはApp.xaml.csページで
private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = new MainPage(); }
と定義されていることを前提とすると、Page1.xaml.csで
private void btn1_Click(object sender, RoutedEventArgs e) { // MainPageインスタンスを取り出す。 MainPage mainPage = App.Current.RootVisual as MainPage; // MainPageにページを遷移する処理を依頼する。 }
と、書くことができます。
子が親のインスタンスを直接いじるのはどうなのよ?という気もしますが、小さいアプリならばこれで十分ではないでしょうか。
2011年2月3日 8:48 -
FrameクラスのNavigatedイベントで子ページのインスタンスを取得する方法はどうでしょうか?
private void Frame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e) { var page1 = e.Content as Page1; if (page1 != null) { // 2度イベントハンドラが登録されないように、念のため一度イベントハンドラを抜いてから登録する。 page1.NavigatePage2Request -= new EventHandler(this.Page1_NavigatePage2Request); page1.NavigatePage2Request += new EventHandler(this.Page1_NavigatePage2Request); } }
2011年2月3日 11:00 -
ご指摘の通り、Navigatedイベントは、Frameが切り替わった瞬間に発生するイベントです。
FrameがNavigatedイベントを発行する↓MainPageのFrame1_NavigatedイベントハンドラでPage1のインスタンスを取得する。↓取得したPage1インスタンスのNavigatePage2Requestイベント(このイベントは自分で定義したイベント)にイベントハンドラを登録する。↓Page1のボタンが押されると、NavigatePage2Requestイベントが発行される。↓Page1_NavigatePage2RequestイベントハンドラでPage2に遷移する。という流れになります。長いですが、コードも載せておきます(C#で申し訳ないです)。MainPage.xaml<UserControl x:Class="NavigationSample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <UserControl.Resources> <uriMapper:UriMapper x:Key="uriMapper"> <uriMapper:UriMapping Uri="Page1" MappedUri="/Page1.xaml" /> <uriMapper:UriMapping Uri="Page2" MappedUri="/Page2.xaml" /> </uriMapper:UriMapper> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal" Background="LightCyan"> <HyperlinkButton x:Name="Page1Button" Content="Page1" NavigateUri="Page1" /> <HyperlinkButton x:Name="Page2Button" Content="Page2" NavigateUri="Page2" /> </StackPanel> <navigation:Frame x:Name="Frame" UriMapper="{StaticResource uriMapper}" Grid.Row="1" Background="LightYellow" /> </Grid> </UserControl>
MainPage.xaml.cspublic partial class MainPage : UserControl { public MainPage() { InitializeComponent(); this.Frame.Navigated += new NavigatedEventHandler(this.Frame_Navigated); } private void Frame_Navigated(object sender, NavigationEventArgs e) { var page1 = e.Content as Page1; if (page1 != null) { // 2度イベントハンドラが登録されないように、念のため一度イベントハンドラを抜いてから登録する。 page1.NavigatePage2Request -= new EventHandler(this.Page1_NavigatePage2Request); page1.NavigatePage2Request += new EventHandler(this.Page1_NavigatePage2Request); } } private void Page1_NavigatePage2Request(object sender, EventArgs e) { // Page1のボタンが押されたとき、Page2に遷移する。 this.Frame.Navigate(this.Page2Button.NavigateUri); } }
Page1.xaml<navigation:Page x:Class="NavigationSample.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="Page1 Page"> <Grid x:Name="LayoutRoot"> <Button x:Name="Page2NavigationButton" Content="Page2へ遷移"/> </Grid> </navigation:Page>
Page1.xaml.cspublic partial class Page1 : Page { public Page1() { InitializeComponent(); this.Page2NavigationButton.Click += new RoutedEventHandler(this.Page2NavigationButton_Click); } /// <summary>Page2へ遷移する要求を発行する。</summary> public event EventHandler NavigatePage2Request; private void Page2NavigationButton_Click(object sender, RoutedEventArgs e) { if (this.NavigatePage2Request != null) { this.NavigatePage2Request(this, EventArgs.Empty); } } }
Page2.xaml<navigation:Page x:Class="NavigationSample.Page2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="Page2 Page"> <Grid x:Name="LayoutRoot"> <TextBlock Text="Page2" FontSize="30"/> </Grid> </navigation:Page>
- 回答としてマーク ohzeki 2011年2月3日 20:36
2011年2月3日 13:55