Mvvm 在WinRT中使用多个ViewModel
操作系统:Windows 8.1 IDE:VS 2013 Express for Windows 项目:环球 目标:Windows 8.1、Phone 8.1 IoC:MEF 我的Windows应用程序基于Windows开发中心的此指南。我正在使用MEF将ViewModels注入到视图中 主页在.Shared项目中,HubPage、ItemPage和SectionPage在透视窗口和电话项目中 每个页面都有自己的ViewModel,位于名为UILogic的程序集中。在启动期间,所有视图模型都成功地注入到这些视图中。但是,通过查看即时窗口,我发现以下绑定错误: Windows 8.1 主页面如下所示:Mvvm 在WinRT中使用多个ViewModel,mvvm,windows-runtime,Mvvm,Windows Runtime,操作系统:Windows 8.1 IDE:VS 2013 Express for Windows 项目:环球 目标:Windows 8.1、Phone 8.1 IoC:MEF 我的Windows应用程序基于Windows开发中心的此指南。我正在使用MEF将ViewModels注入到视图中 主页在.Shared项目中,HubPage、ItemPage和SectionPage在透视窗口和电话项目中 每个页面都有自己的ViewModel,位于名为UILogic的程序集中。在启动期间,所有视图模型都成功
<Grid x:Name="LayoutRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Frame x:Name="rootFrame"/>
这就是我在创业期间所做的:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
...
..
<Hub >
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SectionHeaderClick">
<core:InvokeCommandAction Command="{Binding HubSectionHeaderCommand}"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
<Hub.Header>
<!-- Back button and page title -->
<Grid>
...
..
<Button x:Name="backButton" Style="{StaticResource NavigationBackButtonNormalStyle}"
Margin="0,0,39,0"
VerticalAlignment="Top"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"/>
...
..
</Grid>
</Hub.Header>
...
..
<HubSection IsHeaderInteractive="True"
DataContext="{Binding Section3Items}"
d:DataContext="{Binding Groups[3], Source={d:DesignData Source=../NathsarTS.Shared/DataModel/SampleData.json, Type=data:SampleDataSource}}"
x:Uid="Section3Header" Header="Section 3" Padding="40,40,40,32">
<DataTemplate>
<GridView
x:Name="itemGridView"
ItemsSource="{Binding Items}"
Margin="-9,-14,0,0"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Items In Group"
ItemTemplate="{StaticResource Standard310x260ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ItemClick">
<core:InvokeCommandAction Command="{Binding HubSectionGridItemCommand}"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</GridView>
</DataTemplate>
</HubSection>
...
..
</Hub>
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
this._configuration.WithAssembly(typeof(App).GetTypeInfo().Assembly)
.WithAssembly(typeof(NathsarTS.UILogic.UILogicBusinessLogic).GetTypeInfo().Assembly)
.WithAssembly(typeof(NathsarTS.Common.CommonBusinessLogic).GetTypeInfo().Assembly)
.WithAssembly(typeof(NathsarTS.ODSDocuments.ODSDocumentsBusinessLogic).GetTypeInfo().Assembly);
this._compositionHost = this._configuration.CreateContainer();
await ShowWindow(args);
}
private async Task ShowWindow(LaunchActivatedEventArgs e)
{
MainPage mainPage = Window.Current.Content as MainPage;
Frame rootFrame = null;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (mainPage == null)
{
mainPage = _compositionHost.GetExport<MainPage>();
}
// Retrieve the root Frame to act as the navigation context and navigate to the first page
// Don't change the name of "rootFrame" in MainPage.xaml unless you change it here to match.
rootFrame = (Frame)mainPage.FindName("rootFrame");
if (rootFrame != null)
{
// Associate the frame with a SuspensionManager key.
SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
// TODO: change this value to a cache size that is appropriate for your application
rootFrame.CacheSize = 1;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
// Restore the saved session state only when appropriate
try
{
await SuspensionManager.RestoreAsync();
}
catch (SuspensionManagerException)
{
//Something went wrong restoring state.
//Assume there is no state and continue
}
}
// Place the main page in the current Window.
Window.Current.Content = mainPage;
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
HubPage hubPage = _compositionHost.GetExport<HubPage>();
if (!rootFrame.Navigate(hubPage.GetType(), e.Arguments))
{
throw new Exception("Failed to create initial page");
}
}
}
// Ensure the current window is active
Window.Current.Activate();
}
谢谢你的帮助 能够修复我的副本,并将正确的ViewModel连接到PageView。问题是1的.Navigation在MEF进行初始化后继续重新初始化页面构造函数,2由于某种原因HubPage DataContext丢失 我就是这样解决的:
protected override async Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
Debug.WriteLine("OnLaunchApplicationAsync...");
MainPage mainPage = _compositionHost.GetExport<MainPage>();
Window.Current.Content = mainPage;
Frame rootFrame = (Frame)mainPage.FindName("rootFrame");
if (rootFrame != null)
{
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
HubPage hubPage = _compositionHost.GetExport<HubPage>();
rootFrame.Content = hubPage;
}
}
Window.Current.Activate();
await Task.FromResult<object>(null);
}
我没有在初始启动时使用.Navigation,而是将页面类型分配给了.Content
MainPage InitializeComponent
PropertiesService instantiation
MainPageViewModel instantiation
MainPage OnImportsSatisfied instantiation
HubPage InitializeComponent
HubPageViewModel instantiation
HubPage OnImportsSatisfied instantiation
HubPage InitializeComponent
HubPage OnNavigatedTo instantiation
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
this._configuration.WithAssembly(typeof(App).GetTypeInfo().Assembly)
.WithAssembly(typeof(NathsarTS.UILogic.UILogicBusinessLogic).GetTypeInfo().Assembly)
.WithAssembly(typeof(NathsarTS.Common.CommonBusinessLogic).GetTypeInfo().Assembly)
.WithAssembly(typeof(NathsarTS.ODSDocuments.ODSDocumentsBusinessLogic).GetTypeInfo().Assembly);
this._compositionHost = this._configuration.CreateContainer();
await ShowWindow(args);
}
private async Task ShowWindow(LaunchActivatedEventArgs e)
{
MainPage mainPage = Window.Current.Content as MainPage;
Frame rootFrame = null;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (mainPage == null)
{
mainPage = _compositionHost.GetExport<MainPage>();
}
// Retrieve the root Frame to act as the navigation context and navigate to the first page
// Don't change the name of "rootFrame" in MainPage.xaml unless you change it here to match.
rootFrame = (Frame)mainPage.FindName("rootFrame");
if (rootFrame != null)
{
// Associate the frame with a SuspensionManager key.
SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
// TODO: change this value to a cache size that is appropriate for your application
rootFrame.CacheSize = 1;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
// Restore the saved session state only when appropriate
try
{
await SuspensionManager.RestoreAsync();
}
catch (SuspensionManagerException)
{
//Something went wrong restoring state.
//Assume there is no state and continue
}
}
// Place the main page in the current Window.
Window.Current.Content = mainPage;
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
HubPage hubPage = _compositionHost.GetExport<HubPage>();
if (!rootFrame.Navigate(hubPage.GetType(), e.Arguments))
{
throw new Exception("Failed to create initial page");
}
}
}
// Ensure the current window is active
Window.Current.Activate();
}
protected override async Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
Debug.WriteLine("OnLaunchApplicationAsync...");
MainPage mainPage = _compositionHost.GetExport<MainPage>();
Window.Current.Content = mainPage;
Frame rootFrame = (Frame)mainPage.FindName("rootFrame");
if (rootFrame != null)
{
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
HubPage hubPage = _compositionHost.GetExport<HubPage>();
rootFrame.Content = hubPage;
}
}
Window.Current.Activate();
await Task.FromResult<object>(null);
}