C++/WinRT XAML 控件绑定到 属性

C++/WinRT XAML controls bind to a property

我正在尝试通过引入另一个 ViewModel 来扩展 Bookstore 示例,以便在书店中包含 Sections。在我的案例中,我称它为 'Library'。我很难将书籍添加到第二个 ListView 中显示。在 MainPage 中,除了 MainViewModel(现在显示部分)之外,我还添加了 SubModelView 到 return 当前部分。在我的 Xaml 代码中,我用代码构建了第二个 ListView 来显示书籍,但它不起作用。任何人都可以建议我做错了什么。我在 MainPage 中包含一个 SubModelView 以访问正在创建书籍的当前部分,并在 Xaml 代码中使用它。

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


using namespace winrt;
using namespace Windows::UI::Xaml;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Popups;

namespace winrt::Library::implementation
{
    MainPage::MainPage()
    {
        m_mainViewModel = winrt::make<Library::implementation::LibraryViewModel>();
        InitializeComponent();
    }

    Library::LibraryViewModel MainPage::MainViewModel()
    {
        return m_mainViewModel;
    }

    Library::Section MainPage::SubViewModel()
    {
        m_subViewModel = MainViewModel().Sectioncurrent();
        return m_subViewModel;
    }
}

void winrt::Library::implementation::MainPage::SectionButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    hstring sname{ Section_name().Text().c_str() };
    MainViewModel().Sectioncurrent(sname);
}


void winrt::Library::implementation::MainPage::TotleButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (MainViewModel().Sectioncurrent() == nullptr)
        return;
    hstring bname{ Title_name().Text().c_str() };
    MainViewModel().Sectioncurrent().Bookcurrent(bname);

    Library::Section subsec = SubViewModel();
    Library::Book bk = subsec.Bookcurrent();
    hstring tt = bk.Title();
}
#include "pch.h"
#include "LibraryViewModel.h"
#include "LibraryViewModel.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
// static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::Library::implementation
{
    LibraryViewModel::LibraryViewModel()
    {
        m_section = winrt::single_threaded_observable_vector<Library::Section>();
    }

    Windows::Foundation::Collections::IObservableVector<Library::Section> LibraryViewModel::Sections()
    {
        return m_section;
    }

    void LibraryViewModel::Sectioncurrent(hstring const& sectionname)
    {
        m_sectionCurrent = winrt::make<Library::implementation::Section>(sectionname);
        Sections().Append(m_sectionCurrent);
    }

    Library::Section LibraryViewModel::Sectioncurrent()
    {
        return m_sectionCurrent;
    }

    winrt::event_token LibraryViewModel::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }

    void LibraryViewModel::PropertyChanged(winrt::event_token const& token) noexcept
    {
        m_propertyChanged.remove(token);
    }
}
#include "pch.h"
#include "Section.h"
#include "Section.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
// static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::Library::implementation
{
   // Constructor
   Section::Section(hstring const& name) : m_sectionName{name}
   {
       m_section = winrt::single_threaded_observable_vector<Library::Book>();
   }

   Windows::Foundation::Collections::IObservableVector<Library::Book> Section::Books()
   {
       return m_section;
   }

   void Section::Bookcurrent(hstring const& name)
   {
       m_book = winrt::make<Library::implementation::Book>(name);
       Books().Append(m_book);
   }

   Library::Book Section::Bookcurrent()
   {
       return m_book;
   }

    hstring Section::SectionName()
    {
        return m_sectionName;
    }

    winrt::event_token Section::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }

    void Section::PropertyChanged(winrt::event_token const& token) noexcept
    {
        m_propertyChanged.remove(token);
    }
}
<Page
    x:Class="Library.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Library"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="Section_name" Grid.Row="0" Grid.Column="0" Margin="160,5,5,5" 
                 HorizontalAlignment="Left"
                 MinWidth="200"/>
        <TextBox x:Name="Title_name" Grid.Row="0" Grid.Column="1" Margin="5,5,160,5" 
                 HorizontalAlignment="Right"
                 MinWidth="200"/>
        <Button x:Name="SectionButton" Grid.Row="1" Grid.Column="0" 
                Click="SectionButton_Click" Margin="160,5,5,5"
                HorizontalAlignment="Left">Add Section</Button>
        <Button x:Name="TotleButton" Grid.Row="1" Grid.Column="1" 
                Click="TotleButton_Click" Margin="5,5,160,5"
                HorizontalAlignment="Right">Add Title</Button>
        <ListView x:Name="SectionList"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Grid.Row="2" Grid.Column="0"
                  BorderBrush="Black" BorderThickness="2"
                  Margin="40,10,40,10"
                  ItemsSource="{x:Bind MainViewModel.Sections}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Section">
                    <TextBlock Text="{x:Bind SectionName, Mode=OneWay}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <ListView x:Name="TitleList"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Grid.Row="2" Grid.Column="1"
                  BorderBrush="Black" BorderThickness="2"
                  Margin="40,10,40,10"
                  ItemsSource="{x:Bind SubViewModel.Books}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Book">
                    <TextBlock Text="{x:Bind Title, Mode=OneWay}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button x:Name="Process" Grid.Row="3" Grid.Column="0"
                Grid.ColumnSpan="2"
                HorizontalAlignment="Center"
                Click="Process_Click">PROCESS
        </Button>
    </Grid>
</Page>
import "LibraryViewModel.idl";

namespace Library
{
    [default_interface]
    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
    {
        MainPage();
        LibraryViewModel MainViewModel{ get; };
    }
}
import "SectionViewModel.idl";

namespace Library
{
    runtimeclass LibraryViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        LibraryViewModel();
        Windows.Foundation.Collections.IObservableVector<SectionViewModel> Sections{ get; };
        void SectionViewModel(String sname);
        SectionViewModel SubViewModel{ get; };
    }
}
import "Book.idl";

namespace Library
{
    [bindable]
    runtimeclass SectionViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        SectionViewModel(String name);
        String SectionName{ get; };
        Windows.Foundation.Collections.IObservableVector<Book> Books{ get; };
        void Book(String sname);
        Book BookCurrent{ get; };
    }
}
namespace Library
{
    [bindable]
    runtimeclass Book : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        Book(String title);
        String Title{ get; };
    }
}
#pragma once

#include "MainPage.g.h"
#include "LibraryViewModel.h"

namespace winrt::Library::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();
        Library::LibraryViewModel MainViewModel();
        
        void SectionButton_Click(winrt::Windows::Foundation::IInspectable const& sender, 
            winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
        void TitleButton_Click(winrt::Windows::Foundation::IInspectable const& sender, 
            winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
        void Process_Click(winrt::Windows::Foundation::IInspectable const& sender, 
            winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
    private:
        Library::LibraryViewModel m_mainViewModel{ nullptr };
        Library::SectionViewModel m_sectionCurrent{ nullptr };
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
       
    };
}

namespace winrt::Library::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}
#pragma once
#include "LibraryViewModel.g.h"
#include "SectionViewModel.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
// static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::Library::implementation
{
    struct LibraryViewModel : LibraryViewModelT<LibraryViewModel>
    {
        LibraryViewModel();
        
        Windows::Foundation::Collections::IObservableVector<Library::SectionViewModel> Sections();
        void SectionViewModel(hstring const& sname);
        Library::SectionViewModel SubViewModel();

        winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
        void PropertyChanged(winrt::event_token const& token) noexcept;
    private:
        Windows::Foundation::Collections::IObservableVector<Library::SectionViewModel> m_section{ nullptr };
        Library::SectionViewModel m_sectionCurrent{ nullptr };
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}
namespace winrt::Library::factory_implementation
{
    struct LibraryViewModel : LibraryViewModelT<LibraryViewModel, implementation::LibraryViewModel>
    {
    };
}
#pragma once
#include "SectionViewModel.g.h"
#include "Book.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
// static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::Library::implementation
{
    struct SectionViewModel : SectionViewModelT<SectionViewModel>
    {
        SectionViewModel() = delete;
        SectionViewModel(hstring const& name);
        Windows::Foundation::Collections::IObservableVector<Library::Book> Books();
        hstring SectionName();
        void Book(hstring const& bname);
        Library::Book BookCurrent();
       
        winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
        void PropertyChanged(winrt::event_token const& token) noexcept;
    private:
        Windows::Foundation::Collections::IObservableVector<Library::Book> m_books{ nullptr };
        hstring m_sectionName;
        Library::Book m_bookCurrent{ nullptr };
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}
namespace winrt::Library::factory_implementation
{
    struct SectionViewModel : SectionViewModelT<SectionViewModel, implementation::SectionViewModel>
    {
    };
}
#pragma once
#include "Book.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
// static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::Library::implementation
{
    struct Book : BookT<Book>
    {
        Book() = delete;
        Book(hstring const& title);
       // void Title(hstring const& value);
        hstring Title();
        winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
        void PropertyChanged(winrt::event_token const& token) noexcept;
    private:
        hstring m_title;
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}
namespace winrt::Library::factory_implementation
{
    struct Book : BookT<Book, implementation::Book>
    {
    };
}

根据你的描述和代码,我假设你想在你的图书馆应用程序中添加一个名为 Section 的图层。输入一个Section名称,将多本书添加到添加的Section中,其中包含TextBox控件和Button控件。如果您对以下代码有任何疑虑,请随时与我们联系。

这里有一个示例代码:

Book.idl

namespace Library
{
    runtimeclass Book : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        Book(String title);
        String Title;
    }
}

Book.h

#pragma once
#include "Book.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.

namespace winrt::Library::implementation
{
    struct Book : BookT<Book>
    {
        Book() = default;

        Book(hstring const& title);
        hstring Title();
        void Title(hstring const& value);
        winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
        void PropertyChanged(winrt::event_token const& token) noexcept;
    private:
        winrt::hstring m_title;
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}
namespace winrt::Library::factory_implementation
{
    struct Book : BookT<Book, implementation::Book>
    {
    };
}

Book.cpp

#include "pch.h"
#include "Book.h"
#include "Book.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.

namespace winrt::Library::implementation
{
    Book::Book(hstring const& title):m_title{title}
    {
    }
    hstring Book::Title()
    {
        return m_title;
    }
    void Book::Title(hstring const& value)
    {
        if (m_title != value)
        {
            m_title = value;
            m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Title" });
        }
    }
    winrt::event_token Book::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }
    void Book::PropertyChanged(winrt::event_token const& token) noexcept
    {
        m_propertyChanged.remove(token);
    }
}

Section.idl

import "Book.idl";

namespace Library
{
    runtimeclass Section: Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        Section();
String SectionName{ get; set; };
void BookCurrent(String name);
Book BookCurrent();
Windows.Foundation.Collections.IObservableVector<Book> Books{ get; set; };
    }
}

Section.h

#pragma once
#include "Section.g.h"
#include "Book.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.

namespace winrt::Library::implementation
{
    struct Section : SectionT<Section>
    {
        Section() {
            m_books = winrt::single_threaded_observable_vector<Library::Book>();
        }

        hstring SectionName();
        void SectionName(hstring const& value);
        void BookCurrent(hstring const& name);
        Library::Book BookCurrent();
        Windows::Foundation::Collections::IObservableVector<Library::Book> Books();
        void Books(Windows::Foundation::Collections::IObservableVector<Library::Book> const& value);
        winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
        void PropertyChanged(winrt::event_token const& token) noexcept;

    private:
        hstring m_sectionName;
        Windows::Foundation::Collections::IObservableVector<Library::Book> m_books{ nullptr };
        Library::Book m_book{ nullptr };
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;

    };
}
namespace winrt::Library::factory_implementation
{
    struct Section : SectionT<Section, implementation::Section>
    {
    };
}

Section.cpp

#include "pch.h"
#include "Section.h"
#include "Section.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.

namespace winrt::Library::implementation
{
    hstring Section::SectionName()
    {
        return m_sectionName;
    }
    void Section::SectionName(hstring const& value)
    {
        if (m_sectionName != value)
        {
            m_sectionName = value;
            m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"SectionName" });
        }
    }
    void Section::BookCurrent(hstring const& name)
    {
        m_book = Library::Book{ name };
        m_books.Append(m_book);
        m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Book" });

    }
    Library::Book Section::BookCurrent()
    {
        return m_book;
    }
    Windows::Foundation::Collections::IObservableVector<Library::Book> Section::Books()
    {
        return m_books;
    }
    void Section::Books(Windows::Foundation::Collections::IObservableVector<Library::Book> const& value)
    {
        if (m_books != value)
        {
            m_books = value;
            m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Books" });

        }
    }
    winrt::event_token Section::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }
    void Section::PropertyChanged(winrt::event_token const& token) noexcept
    {
        m_propertyChanged.remove(token);
    }
}

LibraryViewModel.idl

import "Section.idl";

namespace Library
{
    runtimeclass LibraryViewModel: Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        LibraryViewModel();
Section SectionViewModel();
void SectionViewModel(String name);
        Windows.Foundation.Collections.IObservableVector<Section> Sections{ get; };
        Section SectionCurrent{ get; set; };
    }
}

LibraryViewModel.h

#pragma once
#include "LibraryViewModel.g.h"
#include "Section.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.

namespace winrt::Library::implementation
{
    struct LibraryViewModel : LibraryViewModelT<LibraryViewModel>
    {
        LibraryViewModel() {
            m_sections = winrt::single_threaded_observable_vector<Library::Section>();
        }

        Library::Section SectionViewModel();
        void SectionViewModel(hstring const& name);
        Windows::Foundation::Collections::IObservableVector<Library::Section> Sections();
        Library::Section SectionCurrent();
        void SectionCurrent(Library::Section const& value);

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

    private:
        Library::Section m_section{ nullptr };
        Windows::Foundation::Collections::IObservableVector<Library::Section> m_sections{ nullptr };
        Library::Section m_sectionCurrent{ nullptr };
        winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;

    };
}
namespace winrt::Library::factory_implementation
{
    struct LibraryViewModel : LibraryViewModelT<LibraryViewModel, implementation::LibraryViewModel>
    {
    };
}

LibraryViewModel.cpp

#include "pch.h"
#include "LibraryViewModel.h"
#include "LibraryViewModel.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.

namespace winrt::Library::implementation
{
    Library::Section LibraryViewModel::SectionViewModel()
    {
        return m_section;
    }
    void LibraryViewModel::SectionViewModel(hstring const& name)
    {
        m_section = Library::Section();
        m_section.SectionName(name);
        m_sections.Append(m_section);
    }
    Windows::Foundation::Collections::IObservableVector<Library::Section> LibraryViewModel::Sections()
    {
        return m_sections;
    }
    Library::Section LibraryViewModel::SectionCurrent()
    {
        //int t = m_sectionCurrent.Books().Size();
        return m_sectionCurrent;
    }
    void LibraryViewModel::SectionCurrent(Library::Section const& value)
    {
        if (m_sectionCurrent != value)
        {
            m_sectionCurrent = value;
            m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"SubViewModel" });

            m_sections.Append(m_sectionCurrent);
        }
    }
    winrt::event_token LibraryViewModel::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }
    void LibraryViewModel::PropertyChanged(winrt::event_token const& token) noexcept
    {
        m_propertyChanged.remove(token);
    }

}

MainPage.idl

import "BookstoreViewModel.idl";
import "Section.idl";
import "Book.idl";
import "LibraryViewModel.idl";

namespace Library
{
    [default_interface]
    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
    {
        MainPage();

    BookstoreViewModel MainViewModel{ get; };
    LibraryViewModel MyViewModel{ get; };
    Section SubViewModel{ get;};
    Windows.Foundation.Collections.IObservableVector<Book> Books{ get; };

    }
}

MainPage.h

#pragma once

#include "MainPage.g.h"
#include "BookstoreViewModel.h"
#include "Section.h"
#include "LibraryViewModel.h"

namespace winrt::Library::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();
        Library::BookstoreViewModel MainViewModel();

        void Process_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
        Library::Section SubViewModel();
        //void CurrentSection(Library::Section const& value);
        Library::LibraryViewModel MyViewModel();
        Windows::Foundation::Collections::IObservableVector<Library::Book> Books();
    private:
        Library::BookstoreViewModel m_mainViewModel{ nullptr };
        Library::Section m_subViewModel{ nullptr };
        Library::LibraryViewModel m_myViewModel{ nullptr };
        
    public:
        void ListView_SelectionChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::SelectionChangedEventArgs const& e);
        void SectionButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
        void TotleButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
        Windows::Foundation::Collections::IObservableVector<Library::Book> m_books{ nullptr };

    };
}

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

MainPage.cpp

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

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

namespace winrt::Library::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();
        m_mainViewModel = winrt::make<Library::implementation::BookstoreViewModel>();
        m_myViewModel = winrt::make<Library::implementation::LibraryViewModel>();

        m_subViewModel = winrt::make<Library::implementation::Section>();
        m_subViewModel.SectionName(L"sample");
        m_myViewModel.Sections().Append(m_subViewModel);

        m_books = winrt::single_threaded_observable_vector<Library::Book>();
    }

    void MainPage::Process_Click(IInspectable const&, RoutedEventArgs const&)
    {

    }
    Library::BookstoreViewModel MainPage::MainViewModel()
    {
        return m_mainViewModel;
    }
    Library::Section MainPage::SubViewModel()
    {
        m_subViewModel = m_myViewModel.SectionCurrent();
        return m_subViewModel;
    }
    Library::LibraryViewModel MainPage::MyViewModel()
    {
        return m_myViewModel;
    }
    Windows::Foundation::Collections::IObservableVector<Library::Book> MainPage::Books()
    {
        return m_books;

    }
}


void winrt::Library::implementation::MainPage::ListView_SelectionChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::SelectionChangedEventArgs const& e)
{
}


void winrt::Library::implementation::MainPage::SectionButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    hstring sname{ Section_name().Text().c_str() };
    auto section{ Library::Section() };
    section.SectionName(sname);
    m_books.Clear();
    m_myViewModel.SectionCurrent(section);
}


void winrt::Library::implementation::MainPage::TotleButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (m_myViewModel.SectionCurrent() == nullptr)
        return;
    hstring bname{ Title_name().Text().c_str() };
    m_books.Append(Library::Book(bname));
    m_myViewModel.SectionCurrent().Books(m_books);
    auto t = m_myViewModel.SectionCurrent().Books();

    auto t1 = t.Size();
}

MainPage.xaml

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

    <Grid  HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="Section_name" Grid.Row="0" Grid.Column="0" Margin="160,5,5,5" 
                 HorizontalAlignment="Left"
                 MinWidth="200"/>
        <TextBox x:Name="Title_name" Grid.Row="0" Grid.Column="1" Margin="5,5,160,5" 
                 HorizontalAlignment="Right"
                 MinWidth="200"/>
        <Button x:Name="SectionButton" Grid.Row="1" Grid.Column="0" 
                Click="SectionButton_Click" Margin="160,5,5,5"
                HorizontalAlignment="Left">Add Section</Button>
        <Button x:Name="TotleButton" Grid.Row="1" Grid.Column="1" 
                Click="TotleButton_Click" Margin="5,5,160,5"
                HorizontalAlignment="Right">Add Title</Button>

        <ListView x:Name="SectionList"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Grid.Row="2" Grid.Column="0"
                  BorderBrush="Black" BorderThickness="2"
                  Margin="40,10,40,10"
                  ItemsSource="{x:Bind MyViewModel.Sections}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Section">
                    <TextBlock Text="{x:Bind SectionName, Mode=OneWay}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        
        <ListView x:Name="TitleList"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Grid.Row="2" Grid.Column="1"
                  BorderBrush="Black" BorderThickness="2"
                  Margin="40,10,40,10"
                  ItemsSource="{x:Bind Books,Mode=OneWay}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Book">
                    <TextBlock Text="{x:Bind Title, Mode=OneWay}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button x:Name="Process" Grid.Row="3" Grid.Column="0"
                Grid.ColumnSpan="2"
                HorizontalAlignment="Center"
                Click="Process_Click">PROCESS
        </Button>

    </Grid>
</Page>

更新:

请对上面的代码做一些修改:

Section.cpp

void Section::Books(Windows::Foundation::Collections::IObservableVector<Library::Book> const& value)
{
    if (m_books != value)
    {
        m_books = value;
        m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Books" });

    }
    m_books = value;
}

LibraryViewModel.cpp

void LibraryViewModel::SectionCurrent(Library::Section const& value)
{
    if (m_sectionCurrent != value)
    {
        m_sectionCurrent = value;
        m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"SubViewModel" });

        bool flag = false;
        for (int i = 0; i < m_sections.Size(); i++)
        {
            if (m_sections.GetAt(i).SectionName() == value.SectionName())
            {
                flag = true;
                break;
            }
        }
        if (flag == false)
        {
            m_sections.Append(m_sectionCurrent);
        }
    }
}

在MainPage.xaml

中添加SectionList的SelectionChanged
<ListView x:Name="SectionList"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch"
          Grid.Row="2" Grid.Column="0"
          BorderBrush="Black" BorderThickness="2"
          Margin="40,10,40,10"
          SelectionChanged="SectionList_SelectionChanged"
          ItemsSource="{x:Bind MyViewModel.Sections}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Section">
            <TextBlock Text="{x:Bind SectionName, Mode=OneWay}"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

MainPage.xaml.cs

void winrt::Library::implementation::MainPage::SectionButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    hstring sname{ Section_name().Text().c_str() };
    auto section{ Library::Section() };
    section.SectionName(sname);

    m_books.Clear();

    m_myViewModel.SectionCurrent(section);
    SectionList().SelectedValue(section);
}

void winrt::Library::implementation::MainPage::TotleButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    if (m_myViewModel.SectionCurrent() == nullptr)
        return;
    hstring bname{ Title_name().Text().c_str() };
    m_books.Append(Library::Book(bname));
    int size = m_books.Size();
    m_myViewModel.SectionCurrent().Books().Append(Library::Book(bname));  //

}


void winrt::Library::implementation::MainPage::SectionList_SelectionChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::SelectionChangedEventArgs const& e)
{
    auto selectedItem = SectionList().SelectedValue().try_as<Library::Section>();
    m_myViewModel.SectionCurrent(selectedItem);

    if (selectedItem != nullptr)
    {
        auto t1 = selectedItem.SectionName();
        m_books.Clear();
        auto size = selectedItem.Books().Size();
        for (int i = 0; i < size; i++)
        {
            m_books.Append(selectedItem.Books().GetAt(i));
        }
        size = m_books.Size();
    }

}