読者です 読者をやめる 読者になる 読者になる

プログラマーな日々

プログラマーをやっています。好きなツール:WorkFlowy、好きな言語:C#、好きなサービス:Backlog、好きなAWS:AWS Lambda。

ページを遷移する前に検証する

.NET WPF

アプリ実行

名前が入力されたときだけ次のページに受け渡します。

Page1.xaml


Hello.xaml


検証

項目 結果
名前の入力がないとき「続行」をクリックしても遷移しない OK
名前の入力があるとき遷移する OK
遷移すると「戻る」ボタンが有効になる OK
「戻る」ボタンをクリックすると遷移する OK
遷移すると「進む」ボタンが有効になる OK
名前の入力がないとき「続行」をクリックしても遷移しない OK
名前の入力がないとき「進む」ボタンクリックすると遷移する OK

ソースコード

App.xaml
<Application x:Class="Propterty.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="Page1.xaml">
</Application>
Page1.xaml
<Page x:Class="Propterty.Page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
    WindowTitle="あなたは誰?"
    Loaded="Page_Loaded">
    <StackPanel>
        <Label>あなたのお名前は?</Label>
        <TextBox Name="_nameBox"></TextBox>
        <TextBlock>
            <Hyperlink 
                NavigateUri="Hello.xaml"
                Click="Hyperlink_Click">
                続行
            </Hyperlink>
        </TextBlock>
    </StackPanel>
</Page>
Page1.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace Propterty {
    public partial class Page1 : Page {

        /// <summary>
        /// ナビゲーション完了後もアクセスできるようにキャッシュする。
        /// </summary>
        NavigationService _navigation;

        public Page1() {
            InitializeComponent();
        }

        private void Page_Loaded(object sender, RoutedEventArgs e) {
            _navigation = this.NavigationService;
            _navigation.Navigating += new NavigatingCancelEventHandler(_navigation_Navigating);
            _navigation.Navigated += new NavigatedEventHandler(_navigation_Navigated);
        }

        private void Hyperlink_Click(object sender, RoutedEventArgs e) {
            Hello hello = new Hello();
            hello.InputName = _nameBox.Text;
            NavigationService.Navigate(hello);
        }

        /// <summary>
        /// イベントのアンフックと参照のクリアを行う。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _navigation_Navigated(object sender, NavigationEventArgs e) {
            _navigation.Navigating -= _navigation_Navigating;
            _navigation.Navigated -= _navigation_Navigated;
            _navigation = null;
        }

        /// <summary>
        /// 検証
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _navigation_Navigating(object sender, NavigatingCancelEventArgs e) {
            if ((_nameBox.Text.Length == 0) &&
                (e.NavigationMode == NavigationMode.New)) { // 一度訪れたページであれば無条件に遷移できるようにする
                e.Cancel = true;
            }
        }
    }
}
Hello.xaml
<Page x:Class="Propterty.Hello"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
    WindowTitle="こんにちは">
    <StackPanel>
        <Label Name="_name"></Label>
        <TextBlock>さん、こんにちは!</TextBlock>
    </StackPanel>
</Page>
Hello.xaml.cs
using System.Windows.Controls;

namespace Propterty {
    public partial class Hello : Page {
        public string InputName {
            set { _name.Content = value; }
        }

        public Hello() {
            InitializeComponent();
        }
    }
}

参考

NavigationService.Navigating イベント (System.Windows.Navigation)
新しいナビゲーションが要求されると発生します。 ...

NavigationService.Navigated イベント (System.Windows.Navigation)
移動先のコンテンツが見つかったときに発生します。この時点で Content プロパティからコンテンツを取得できますが、読み込みはまだ完了していない可能性があります。 ...

NavigatingCancelEventArgs クラス (System.Windows.Navigation)
Navigating イベントにデータを提供します。 ...

NavigatingCancelEventArgs.NavigationMode プロパティ (System.Windows.Navigation)
行われているナビゲーションの種類を示す NavigationMode 値を取得します。 ...