0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++/WinRTでUWPその11 複数ウインドウの表示とUIの更新と その1.

Last updated at Posted at 2021-06-26

#1.今回やること
AppWindowを使用して複数のウインドウを表示します。
・表示するだけではあれなので、それぞれのウインドウから他のウインドウにあるTextBoxの文字を更新できるようにしていきます。
AppWindowの概要はここ。
サンプルはここ
UIの更新はこちら
・今回もほぼMSのwebページに書かれていることをやります。

#2. 雛型の作成

##2-0. TextBoxにバインドするStringViewModelの作成
・いつものように作成します。その7で作ったまんまです。

StringViewModel.idl
namespace appwin_1
{
    [Windows.UI.Xaml.Data.Bindable]
    runtimeclass StringViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        StringViewModel();
        String DataString;
    }
}

StringViewModel.h
#pragma once

#include "StringViewModel.g.h"

namespace winrt::appwin_1::implementation
{
    struct StringViewModel : StringViewModelT<StringViewModel>
    {
        StringViewModel();
        StringViewModel(const winrt::hstring value);

        void DataString(winrt::hstring const& value);
        winrt::hstring DataString();

        winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
        void PropertyChanged(winrt::event_token const& token) noexcept;

    private:

        winrt::hstring m_DataString;
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}

namespace winrt::appwin_1::factory_implementation
{
    struct StringViewModel : StringViewModelT<StringViewModel, implementation::StringViewModel>
    {
    };
}

StringViewModel.cpp
#include "pch.h"
#include "StringViewModel.h"
#if __has_include("StringViewModel.g.cpp")
#include "StringViewModel.g.cpp"
#endif

namespace winrt::appwin_1::implementation
{
    StringViewModel::StringViewModel() : m_DataString(L"めいんぺ~~じ")
    {
    }
    StringViewModel::StringViewModel(const winrt::hstring value)
    {
        m_DataString = value;
    }
    void StringViewModel::DataString(winrt::hstring const& value)
    {
        m_DataString = value;
        m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"DataString" });
    }
    winrt::hstring StringViewModel::DataString()
    {
        return m_DataString;
    }
    winrt::event_token StringViewModel::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }
    void StringViewModel::PropertyChanged(winrt::event_token const& token) noexcept
    {
        m_propertyChanged.remove(token);
    }
}

##2-1. MainPageの変更
・Blank App(C++/WinRT)のプロジェクトテンプレートより、名前は「appwin_1」にして「MainPage」はこんな感じにしました。
・バインド関連の設定も忘れずにしてくださいね。

MainPage.xaml

<Page
    x:Class="appwin_1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:appwin_1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid RequestedTheme="Default">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="1*" />
            <RowDefinition Height="1*" />
            <RowDefinition Height="4*" />
        </Grid.RowDefinitions>
        <Button x:Name="make_blank1" Content="make_blank1" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>
        <Button x:Name="send_blank1_navi1" Content="send_blank1_navi1" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>
        <Button x:Name="send_blank1_navi2" Content="send_blank1_navi2" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>
        <TextBox x:Name="main_text" Text="{x:Bind MainString.DataString, Mode=OneWay}" Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>

    </Grid>
</Page>

```

```xml:MainPage.idl

import "StringViewModel.idl";

namespace appwin_1
{
    [default_interface]
    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
    {
        MainPage();
        StringViewModel MainString{ get; };
    }
}

```

```cpp:MainPage.h

#pragma once

#include "MainPage.g.h"
#include "StringViewModel.h"

namespace winrt::appwin_1::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();

        appwin_1::StringViewModel MainString();

    private:
        appwin_1::StringViewModel m_mainString{ nullptr };

    };
}

namespace winrt::appwin_1::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}

```

```cpp:MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();

        m_mainString = make<appwin_1::implementation::StringViewModel>();
    }
    appwin_1::StringViewModel MainPage::MainString()
    {
        return m_mainString;
    }
}

```

![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/f14b0649-823a-f1e1-df96-c20863702a67.png)
・今回はWInRTで作成しているので、右クリックしても例外は発生しません。


##2-2. BlankPage1の追加
・「メニュー」→「プロジェクト」→「モジュールの追加」より「Blank Page(C++/WinRT)」を選び、名前は「BlankPage1」として「追加」します。
![2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/ad050eb8-fc98-3c89-433b-da53060633b3.png)
![2-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/33a0a991-20b4-fe8a-337a-a4911e20663e.png)
![2-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/ebef3034-16ea-34f1-161f-2285ef1663d2.png)


・「BlankPage.xaml」にも邪魔な「Click Me」ボタンがついてくるので、削除して以下のようにしました。
・「BlankPage.xaml」のみ載せますが、「.h」や「.cpp」からも削除してください。

```xml:BlankPage1.xaml
<Page
    x:Class="appwin_1.BlankPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:appwin_1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid RequestedTheme="Default">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="1*" />
            <RowDefinition Height="1*" />
            <RowDefinition Height="4*" />
        </Grid.RowDefinitions>
        <Button x:Name="send_Mainpage_navi" Content="send_Mainpage_navi" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>
        <Button x:Name="send_Mainpage_global" Content="send_Mainpage_global" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>
        <Button x:Name="send_Mainpage_mem_func" Content="send_Mainpage_mem_func" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>
        <TextBox x:Name="blank1_text" Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="24" Margin="5,5,5,5"/>

    </Grid>
</Page>

```

・これで準備が整いました。次はblank1ウインドウを表示させます。

#3. Blank1の表示

##3-1. MainPage.hへ追加
・MainPage.hへ「winrt/Windows.UI.WindowManagement.h」「winrt/Windows.UI.Xaml.Hosting.h」と「BlankPage1.h」を追加します。
・さらにメンバに「blank1Window」と「blank1Frame」を追加します。このメンバを通して、ウインドウの作成とUIの更新をしていきます。

```cpp:MainPage.h
#pragma once

#include "MainPage.g.h"
#include "StringViewModel.h"

//このヘッダーを追加
#include "winrt/Windows.UI.WindowManagement.h"
#include "winrt/Windows.UI.Xaml.Hosting.h"
#include "BlankPage1.h"

namespace winrt::appwin_1::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();
        appwin_1::StringViewModel MainString();

        //ここAppWindowとFrame追加(Blank1の表示)
        Windows::UI::WindowManagement::AppWindow blank1Window{ nullptr };
        Windows::UI::Xaml::Controls::Frame blank1Frame1{};

    private:
        appwin_1::StringViewModel m_mainString{ nullptr };

    };
}

namespace winrt::appwin_1::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}

```

##3-2. MainPage.cppへ追加
・MainPage.xamlのmake_blank1にClickを追加して、Clickイベントハンドラを追加してください。そしてイベントハンドラの戻り値の型は「IAsyncAction」へ変更してください。ここも[その7](https://qiita.com/lilac0011/items/54da15cc506b59e893d8)でやりましたね。
・その後、「TryCreateAsync」「Navigate」「SetAppWindowContent」「TryShowAsync」の順に呼び出すとBlank1ウインドウが表示されます。MFCだとモードレスダイアログを表示させるのと同じような感じで、簡単にできます。
・「Title」は半分蛇足です。これが無いと、Blank1のタイトルには「appwin_1」しか表示されないので。

```cpp:MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();

        m_mainString = make<appwin_1::implementation::StringViewModel>();
    }
    appwin_1::StringViewModel MainPage::MainString()
    {
        return m_mainString;
    }
}

winrt::Windows::Foundation::IAsyncAction winrt::appwin_1::implementation::MainPage::make_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    //ここに追加(Blank1の表示)
    if (blank1Window == nullptr)
    {
        blank1Window = co_await winrt::Windows::UI::WindowManagement::AppWindow::TryCreateAsync();

        blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>());

        winrt::Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetAppWindowContent(blank1Window, blank1Frame);
    }

    co_await blank1Window.TryShowAsync();
    blank1Window.Title(L"Blank1");
}

```

![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/b02ec6a9-5171-87b4-0d2c-2b726b1e60b8.png)


#4. MainPageからBlankPage1のUIを更新する。
・[3.ページ間での情報の受け渡し](https://docs.microsoft.com/ja-jp/windows/apps/design/basics/navigate-between-two-pages#3-pass-information-between-pages)のやり方でMainPageからBlankPage1のUIを更新します。
・mainPageからBlank1のUIを更新するのは簡単で、以下の①②を実装するだけです。
①更新元(MainPage)で「Navigate()」を追加する。
②更新先(BlankPage1)で「OnNavigatedTo()メンバ関数を追加する。
(MSのwebページでは「オーバーライド」って書いてあるけど、overrideを追加するとエラーになるから注意!)
・では早速実装します。

##4-1. MainPageの更新
・「MainPage.xaml」のsend_blank1_navi1にClickのイベントハンドラを追加してください。
・その後、「MainPage.cpp」のsend_blank1_navi1_Click()にNavigate()を一行追加します。

```cpp:MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();

        m_mainString = make<appwin_1::implementation::StringViewModel>();
    }
    appwin_1::StringViewModel MainPage::MainString()
    {
        return m_mainString;
    }
}

winrt::Windows::Foundation::IAsyncAction winrt::appwin_1::implementation::MainPage::make_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (blank1Window == nullptr)
    {
        blank1Window = co_await winrt::Windows::UI::WindowManagement::AppWindow::TryCreateAsync();

        blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>());

        winrt::Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetAppWindowContent(blank1Window, blank1Frame);
    }

    co_await blank1Window.TryShowAsync();
    blank1Window.Title(L"Blank1");
}


void winrt::appwin_1::implementation::MainPage::send_blank1_navi1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    //Navigateの追加
    blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>(), winrt::box_value(L"めいんぺ~~じから ぶらんく1へ"));
}

```

##4-2. BlankPage1の更新
・BlankPage1.hに「OnNavigatedTo()」メンバ関数を追加します。これは普通にキーボードで。

```cpp:BlankPage1.h
#pragma once

#include "BlankPage1.g.h"

namespace winrt::appwin_1::implementation
{
    struct BlankPage1 : BlankPage1T<BlankPage1>
    {
        BlankPage1();

        //OnNavigatedToを追加
        void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e) ;
    };
}

namespace winrt::appwin_1::factory_implementation
{
    struct BlankPage1 : BlankPage1T<BlankPage1, implementation::BlankPage1>
    {
    };
}

```

・BlankPage1.cppに「OnNavigateTo()」の実装をします。
・BlankPage1の起動時にも「OnNavigatedTo()」が呼び出されます。そのときはe.Parametor()がnullptrとなっています。そのときはおとなしくreturn。最初これを知らないで例外が出たorz

```cpp:BlankPage1.cpp
#include "pch.h"
#include "BlankPage1.h"
#if __has_include("BlankPage1.g.cpp")
#include "BlankPage1.g.cpp"
#endif

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    BlankPage1::BlankPage1()
    {
        InitializeComponent();
    }

    void BlankPage1::OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e)
    {
        //BlankPage1起動時はe.Parameter() == nullptrです。そのときは何もしない。
        if (e.Parameter() == nullptr)
            return;

        auto propertyValue{ e.Parameter().as < Windows::Foundation::IPropertyValue>() };

        if (propertyValue.Type() == Windows::Foundation::PropertyType::String)
            blank1_text().Text(winrt::unbox_value<winrt::hstring>(e.Parameter()));
        else
            blank1_text().Text(L"文字列じゃないよ!");
    }
}

```


![4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/3b3f6b5a-014e-599f-c4b3-765d89937c70.png)


##4-3. MainPageをBlankPage1にする
・this->Frame()のNavigate()を呼び出すと、MainPageをBlankPage1へ遷移できます。ナビゲートはこっちの方が本来の使い方ですけどね。
・それではMainPageのsend_blank_navi2にClickのイベントハンドラを追加してみましょう。

```cpp:MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();

        m_mainString = make<appwin_1::implementation::StringViewModel>();
    }
    appwin_1::StringViewModel MainPage::MainString()
    {
        return m_mainString;
    }

}

winrt::Windows::Foundation::IAsyncAction winrt::appwin_1::implementation::MainPage::make_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (blank1Window == nullptr)
    {
        blank1Window = co_await winrt::Windows::UI::WindowManagement::AppWindow::TryCreateAsync();

        blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>());

        winrt::Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetAppWindowContent(blank1Window, blank1Frame);
    }

    co_await blank1Window.TryShowAsync();
    blank1Window.Title(L"Blank1");
}

void winrt::appwin_1::implementation::MainPage::send_blank1_navi1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    //Navigateの追加
    blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>(), winrt::box_value(L"めいんぺ~~じから ぶらんく1へ"));

}

void winrt::appwin_1::implementation::MainPage::send_blank1_navi2_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    //Navigateの追加
    this->Frame().Navigate(xaml_typename<appwin_1::BlankPage1>(), winrt::box_value(L"めいんぺ~~じから ぶらんく1へ"));
}

```

・両方クリックしてどうなるか確かめてみてください。
![4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/1c1b9a90-a394-1a50-24cd-eddfa55c613f.png)


##4-4. MainPageからBlancPage1を閉じる
・MainPage.xamlを以下のように変更して、「close_blank1」を追加しClickのイベントハンドラまで追加しました。
・そして、close_blank1_Clickの戻り値の型をIAsyncActionへ変更してから編集です。
・CloseAsync()を追加して、blank1Windowをnullptrにするだけです。
・brank1Frameはnullptrにしていませんが、何故かはやって確かめてください。
![4-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/a957c068-ce7d-2c19-03db-1925685183da.png)

```cpp:MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();

        m_mainString = make<appwin_1::implementation::StringViewModel>();
    }
    appwin_1::StringViewModel MainPage::MainString()
    {
        return m_mainString;
    }

}

winrt::Windows::Foundation::IAsyncAction winrt::appwin_1::implementation::MainPage::make_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (blank1Window == nullptr)
    {
        blank1Window = co_await winrt::Windows::UI::WindowManagement::AppWindow::TryCreateAsync();

        blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>());

        winrt::Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetAppWindowContent(blank1Window, blank1Frame);
    }

    co_await blank1Window.TryShowAsync();
    blank1Window.Title(L"Blank1");
}

void winrt::appwin_1::implementation::MainPage::send_blank1_navi1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>(), winrt::box_value(L"めいんぺ~~じから ぶらんく1へ"));
}

void winrt::appwin_1::implementation::MainPage::send_blank1_navi2_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    this->Frame().Navigate(xaml_typename<appwin_1::BlankPage1>(), winrt::box_value(L"めいんぺ~~じから ぶらんく1へ"));
}

winrt::Windows::Foundation::IAsyncAction winrt::appwin_1::implementation::MainPage::close_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (blank1Window == nullptr)
        return;

    //CloseAsyncの追加
    co_await blank1Window.CloseAsync();
    blank1Window = nullptr;
}

```

#5. BlankPage1からMainPageのUIを更新する?
・ここまでは簡単にできたので、今度はBlankPage1からMainPageのTextBoxを更新できるか試してみましょう。
・4.でやったのとは逆にBlankPage1でNavigate()を呼び出し、MainPageにOnNavigatedTo()の実装をするだけです。
・それではやってみましょう

##5-1. BlankPage1
・send_Mainpage_naviにClickのイベントハンドラを追加し、mainFrameを追加。それを通してMainPageのUI更新を試みます。
・xamlは省略して、.hと.cppのみですが。

```cpp:BlankPage1.h
#pragma once

#include "BlankPage1.g.h"

namespace winrt::appwin_1::implementation
{
    struct BlankPage1 : BlankPage1T<BlankPage1>
    {
        BlankPage1();

        //mainFrame追加
        Windows::UI::Xaml::Controls::Frame mainFrame{};

        void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e) ;
        void send_Mainpage_navi_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
    };
}

namespace winrt::appwin_1::factory_implementation
{
    struct BlankPage1 : BlankPage1T<BlankPage1, implementation::BlankPage1>
    {
    };
}

```

```cpp:BlankPage1.cpp
#include "pch.h"
#include "BlankPage1.h"
#if __has_include("BlankPage1.g.cpp")
#include "BlankPage1.g.cpp"
#endif

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    BlankPage1::BlankPage1()
    {
        InitializeComponent();
    }

    void BlankPage1::OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e)
    {
        //BlankPage1起動時はe.Parameter() == nullptrです。そのときは何もしない。
        if (e.Parameter() == nullptr)
            return;

        auto propertyValue{ e.Parameter().as < Windows::Foundation::IPropertyValue>() };

        if (propertyValue.Type() == Windows::Foundation::PropertyType::String)
            blank1_text().Text(winrt::unbox_value<winrt::hstring>(e.Parameter()));
        else
            blank1_text().Text(L"文字列じゃないよ!");
    }
}


void winrt::appwin_1::implementation::BlankPage1::send_Mainpage_navi_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    //Navigate追加
    mainFrame.Navigate(xaml_typename<appwin_1::MainPage>(), winrt::box_value(L"ぶらんく1からめいんぺ~~~~じへ"));
}

```

##5-2. MainPage
・MainPageにはNavigatedToの実装をします。BlankPage1とほぼ同じです。
・何か問題があり、UIが更新されなかった時のためにMainPageまで来たことをしめすメッセージダイアログを表示させます。MainPage→BlankPage1は何の問題も無くできたので、BlankPage1→MainPageも何の問題も無くできると思いますが。

```cpp:MainPage.h
#include "StringViewModel.h"

//このヘッダーを追加
#include "winrt/Windows.UI.WindowManagement.h"
#include "winrt/Windows.UI.Xaml.Hosting.h"
#include "BlankPage1.h"

namespace winrt::appwin_1::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();
        appwin_1::StringViewModel MainString();

        Windows::UI::WindowManagement::AppWindow blank1Window{ nullptr };
        Windows::UI::Xaml::Controls::Frame blank1Frame{};

        //NavigatedToの追加
        void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e);

    private:
        appwin_1::StringViewModel m_mainString{ nullptr };

    public:
        winrt::Windows::Foundation::IAsyncAction make_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
        void send_blank1_navi1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
        void send_blank1_navi2_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
        winrt::Windows::Foundation::IAsyncAction close_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
    };
}

namespace winrt::appwin_1::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}

```

```cpp:MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"
#include <winrt/Windows.UI.Popups.h>

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::appwin_1::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();

        m_mainString = make<appwin_1::implementation::StringViewModel>();
    }
    appwin_1::StringViewModel MainPage::MainString()
    {
        return m_mainString;
    }

    void MainPage::OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e)
    {
        //NavigatedToの実装追加!
        if (e.Parameter() == nullptr)
            return;

        hstring blank1mes = winrt::unbox_value<winrt::hstring>(e.Parameter());
        if (blank1mes == L"")
            return;

        auto propertyValue{ e.Parameter().as < Windows::Foundation::IPropertyValue>() };

        if (propertyValue.Type() == Windows::Foundation::PropertyType::String)
            main_text().Text(blank1mes);
        else
            main_text().Text(L"文字列じゃないよ!");

        //念のためちゃんと届いていることを確認するためのメッセージダイアログ
        Windows::UI::Popups::MessageDialog msg{ blank1mes,L"とどいたよ~~~" };
        msg.ShowAsync();
    }

}

winrt::Windows::Foundation::IAsyncAction winrt::appwin_1::implementation::MainPage::make_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (blank1Window == nullptr)
    {
        blank1Window = co_await winrt::Windows::UI::WindowManagement::AppWindow::TryCreateAsync();

        blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>());

        winrt::Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetAppWindowContent(blank1Window, blank1Frame);
    }

    co_await blank1Window.TryShowAsync();
    blank1Window.Title(L"Blank1");
}

void winrt::appwin_1::implementation::MainPage::send_blank1_navi1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    blank1Frame.Navigate(xaml_typename<appwin_1::BlankPage1>(), winrt::box_value(L"めいんぺ~~じから ぶらんく1へ"));
}

void winrt::appwin_1::implementation::MainPage::send_blank1_navi2_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    this->Frame().Navigate(xaml_typename<appwin_1::BlankPage1>(), winrt::box_value(L"めいんぺ~~じから ぶらんく1へ"));
}

winrt::Windows::Foundation::IAsyncAction winrt::appwin_1::implementation::MainPage::close_blank1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (blank1Window == nullptr)
        return;

    co_await blank1Window.CloseAsync();
    blank1Window = nullptr;
}

```

・でやってみたのが、下です。
![5-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/63858262-8e2b-32b6-e5a6-4806c21a54f8.png)

・大方の予想通り、BlankPage1からMainPageのUIをNavigate()で簡単に更新できません。NavigatedTo関数までは届いているのですが、そこでmain_textが更新できません。
・コンテキストを呼んだり、winrt::resume_foregroundを呼んだりしたのですけど、何故か駄目でした。

#次回へ続く
・というわけで、次回はBlankPage1からMainPageのTextBoxを更新するのをやります。
・BlankWindowのsend_Mainpage_globalとsend_Mainpage_mem_funcの実装ですね。
・一つはglobalって書いてあるから・・・
・もう一つはMSの[AppWindowのサンプル](https://github.com/microsoft/Windows-universal-samples/tree/main/Samples/AppWindow/cppwinrt)等でやっているstaticな・・・でやります。

[もくじへ](https://qiita.com/lilac0011/items/f53f7401ea7da31e3a0b)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?