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();
}
}
我正在尝试通过引入另一个 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();
}
}