操作系统:Windows 8.1
IDE :VS 2013 Express for Windows
项目:通用
目标:Windows 8.1,Phone 8.1
IoC :MEF
我的Windows应用程序基于本指南" Hierarchical navigation, start to finish"在 Windows开发人员中心上。我使用MEF将ViewModel注入视图。
MainPage 位于 .Shared Project 和 HubPage , ItemPage 和 SectionPage < / strong>在视角窗口和电话项目。
每个页面都有自己的 ViewModel ,位于程序集中,名为 UILogic 。在启动期间,所有 ViewModels 都成功注入视图。但是,查看立即窗口,我得到此绑定错误:
Windows 8.1
Error: BindingExpression path error: 'HubSectionHeaderCommand' property not found on 'NathsarTS.UILogic.ViewModels.MainPageViewModel, NathsarTS.UILogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='HubSectionHeaderCommand' DataItem='NathsarTS.UILogic.ViewModels.MainPageViewModel, NathsarTS.UILogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Microsoft.Xaml.Interactions.Core.InvokeCommandAction' (Name='null'); target property is 'Command' (type 'ICommand')
Error: BindingExpression path error: 'DefaultDataModel' property not found on 'NathsarTS.UILogic.ViewModels.MainPageViewModel, NathsarTS.UILogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='DefaultDataModel' DataItem='NathsarTS.UILogic.ViewModels.MainPageViewModel, NathsarTS.UILogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Data.CollectionViewSource' (Name='null'); target property is 'Source' (type 'Object')
Error: BindingExpression path error: 'NavigationHelper' property not found on 'NathsarTS.Views.HubPage'. BindingExpression: Path='NavigationHelper.GoBackCommand' DataItem='NathsarTS.Views.HubPage'; target element is 'Windows.UI.Xaml.Controls.Button' (Name='backButton'); target property is 'Command' (type 'ICommand')
Error: BindingExpression path error: 'Section3Items' property not found on 'NathsarTS.UILogic.ViewModels.MainPageViewModel, NathsarTS.UILogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='Section3Items' DataItem='NathsarTS.UILogic.ViewModels.MainPageViewModel, NathsarTS.UILogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.HubSection' (Name='null'); target property is 'DataContext' (type 'Object')
MainPage 如下所示:
<Grid x:Name="LayoutRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Frame x:Name="rootFrame"/>
HubPage 看起来像这样在启动时也会导航:
<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>
我的绑定报告未在 MainPageViewModel 上报告,但它们在 HubPageViewModel 中定义。
我 MEF 以这种方式注入 ViewModels :
[Export(typeof(HubPage))]
public sealed partial class HubPage : Page
{
public HubPage()
{
this.InitializeComponent();
Debug.WriteLine("HubPage InitializeComponent");
}
[Import]
public NathsarTS.UILogic.Interfaces.IHubPageViewModel ViewModel
{
set
{
this.DataContext = value;
}
get
{
return DataContext as NathsarTS.UILogic.Interfaces.IHubPageViewModel;
}
}
/// <summary>
/// Called when a part's imports have been satisfied and it is safe to use.
/// </summary>
[OnImportsSatisfied]
public void OnImportsSatisfied()
{
// IPartImportsSatisfiedNotification is useful when you want to coordinate doing some work
// with imported parts independent of when the UI is visible.
Debug.WriteLine("HubPage OnImportsSatisfied instantiation");
//NathsarTS.UILogic.Interfaces.IObservableService ObservableService = ServiceLocator.Current.GetInstance<NathsarTS.UILogic.Interfaces.IObservableService>();
this.ViewModel.NavigationHelper = new NathsarTS.Common.Logic.NavigationHelper(this);
this.ViewModel.NavigationHelper.LoadState += this.ViewModel.NavigationHelperLoadState;
}
}
WinRT 中是否允许 ViewModels PageView ?
IN ADDTION :我在启动时也注意到这一点,HubPage正在初始化两次。为什么:
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();
}
谢谢你的帮助!..
答案 0 :(得分:0)
能够修复我的重复内容并正确地将 ViewModel 连接到 PageView 。问题是。 Navigation 1)在 MEF 进行初始化后继续重新初始化 Page 构造函数,2)由于某种原因< strong> 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);
}
而不是在初始启动时使用。导航,我只是将页面 类型分配给。内容