- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个名为 ModuleMenu 的模块。在这个模块中,我有一个名为 MenuView 的 UserControl 和一个名为 UserControlViewModel 的相应 ViewModel。我还有一个名为 Module 的类。全部代码如下:
菜单 View .xmal
<UserControl ..............>
<ListBox ItemsSource="{Binding MenuItems, Converter={StaticResource dummy}}" DisplayMemberPath="MenuItemName" SelectedItem="{Binding SelectedMenuItem}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="10,0" />
</Style>
</ListBox.Resources>
</ListBox>
</UserControl>
菜单 View .xaml.cs
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class MenuView : UserControl
{
public MenuView()
{
InitializeComponent();
}
}
UserControlViewModel.cs
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MenuViewModel : ViewModelBase
{
IServiceFactory _ServiceFactory;
[ImportingConstructor]
public MenuViewModel(IServiceFactory serviceFactory)
{
_ServiceFactory = serviceFactory;
}
protected override void OnViewLoaded()
{
_MenuItems = new ObservableCollection<MenuItem>();
WithClient<IMenuItemService>(_ServiceFactory.CreateClient<IMenuItemService>(), menuItemClient =>
{
MenuItem[] menuItems = menuItemClient.GetAllParentMenuItemsWithChildren();
if (menuItems != null)
{
foreach (MenuItem menuItem in menuItems)
{
_MenuItems.Add(menuItem);
}
_SelectedMenuItem = _MenuItems[2];
}
});
}
private ObservableCollection<MenuItem> _MenuItems;
public ObservableCollection<MenuItem> MenuItems
{
get
{
return _MenuItems;
}
set
{
if (_MenuItems != value)
{
_MenuItems = value;
OnPropertyChanged(() => MenuItems, false);
}
}
}
private MenuItem _SelectedMenuItem;
public MenuItem SelectedMenuItem
{
get
{
return _SelectedMenuItem;
}
set
{
if (_SelectedMenuItem != value)
{
_SelectedMenuItem = value;
OnPropertyChanged(() => SelectedMenuItem);
}
}
}
}
模块.cs
[ModuleExport(typeof(Module), InitializationMode=InitializationMode.WhenAvailable)]
public class Module : IModule
{
IRegionManager _regionManager;
[ImportingConstructor]
public Module(IRegionManager regionManager)
{
_regionManager = regionManager;
}
public void Initialize()
{
_regionManager.Regions[RegionNames.MenubarRegion].Add(ServiceLocator.Current.GetInstance<MenuView>());
}
}
现在在我的主项目中有一个名为 BootStrapper.cs 的类,如下所示:
public class Bootstrapper : MefBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.GetExportedValue<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
App.Current.MainWindow = (Window)Shell;
App.Current.MainWindow.Show();
}
protected override void ConfigureAggregateCatalog()
{
base.ConfigureAggregateCatalog();
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleMenu.Module).Assembly));
}
}
在我的 App.xaml 中:
<Application ..............>
<Application.Resources>
<DataTemplate DataType="{x:Type modMenu:MenuViewModel}">
<modMenu:MenuView />
</DataTemplate>
</Application.Resources>
</Application>
最后在 App.xaml.cs 中:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
}
当我运行应用程序时,我得到了预期的 shell。它向我显示 MenuView,但未加载 MenuView 中的数据。我尝试使用虚拟转换器对其进行调试,结果显示 viewModel 从未初始化。
那么,现在我的问题是如何初始化 viewModel?
更新:
尝试你的代码后,我得到如下异常:
尝试将 View 添加到区域“MenubarRegion”时发生异常。
- The most likely causing exception was was:
'Microsoft.Practices.ServiceLocation.ActivationException: Activation
error occured while trying to get instance of type MenuView, key "" --->
Microsoft.Practices.ServiceLocation.ActivationException: Activation
error occured while trying to get instance of type MenuView, key ""
at Microsoft.Practices.Prism.MefExtensions.MefServiceLocatorAdapter
.DoGetInstance(Type serviceType, String key)
at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase
.GetInstance(Type serviceType, String key)
--- End of inner exception stack trace ---
at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase
.GetInstance(Type serviceType, String key)
at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase
.GetInstance(Type serviceType)
at Microsoft.Practices.Prism.Regions.RegionViewRegistry
.CreateInstance(Type type)
at Microsoft.Practices.Prism.Regions.RegionViewRegistry
.<>c__DisplayClass1.<RegisterViewWithRegion>b__0()
at Microsoft.Practices.Prism.Regions.Behaviors
.AutoPopulateRegionBehavior
.OnViewRegistered(Object sender, ViewRegisteredEventArgs e)'.
But also check the InnerExceptions for more detail or call
.GetRootException().
当我查看内部异常时,我收到以下错误消息:
{"Activation error occured while trying to get instance of type MenuView, key \"\""}
更新2:
这是 ServiceFactory 类型的导出:
[Export(typeof(IServiceFactory))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ServiceFactory : IServiceFactory
{
public T CreateClient<T>() where T : IServiceContract
{
return ObjectBase.Container.GetExportedValue<T>();
}
}
最佳答案
您将 DataTemplate
定义为 View 模型的 View ,但实际上并不使用它。
有很多方法可以解决您使用 Prism 的问题,请引用 this topic .
您可以在 XAML 中设置 View 的 DataContext
属性:
<UserControl.DataContext>
<my:MyViewModel/>
</UserControl.DataContext>
您可以在 View 的构造函数中创建一个 View 模型:
public MyView()
{
InitializeComponent();
this.DataContext = new MyViewModel();
}
更好的方法是通过依赖注入(inject)导入 View 模型:
[ImportingConstructor]
public MyView(MyViewModel viewModel)
{
InitializeComponent();
this.DataContext = viewModel;
}
您可以使用 Prism 的 View 模型定位服务:
<MyView prism:ViewModelLocator.AutoWireViewModel="True"/>
最后但同样重要的是:您也可以使用 DataTemplate
,但您应该设置对象的 DataContext
以让 WPF 为您创建 View ,并且不要在代码中创建 View 。
更新:因此,您想使用 DataTemplate
功能。好吧,这不是“Prism ”做事的方式,因为在那种情况下, View 将由 WPF 创建,而不是由 Prism 的 IRegion
创建。但无论如何这是可能的。
我将解释不同之处:在所有其他 (Prism) 方法中, View 是“主”,它将首先创建,然后将创建适当的 View 模型并将其附加到 View 。在 Prism 中,您可以定义应创建哪些 View 、何时(导航)和何处(区域)。在DataTemplate
方法中,viewmodel(数据)是'master',它首先被创建,WPF 决定如何显示它们创建一个 View 。所以在这种情况下,您不能使用 Prism 的区域和导航,因为 WPF 会处理所有事情。
所以我真的建议您为此使用上述任何一种方法,但不要使用 DataTemplate
方法。
您按如下方式创建 View :
_regionManager.Regions[RegionNames.MenubarRegion].Add(ServiceLocator.Current.GetInstance<MenuView>());
我建议您将其更改为:
_regionManager.RegisterViewWithRegion(RegionNames.MenubarRegion, typeof(MenuView));
直接使用 ServiceLocator
不是一个好的模式(除非您无法避免),所以让 Prism 为您实例化 View 。
在 View 的构造函数中,只需添加 View 模型的依赖注入(inject),并将 View 的 DataContext
设置到它。瞧!你已经知道了。
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class MenuView : UserControl
{
[ImportingConstructor]
public MenuView(MenuViewModel viewModel)
{
this.InitializeComponent();
this.DataContext = viewModel;
}
}
使用 DataTemplate
,您只能以“旧的普通 WPF 方式”来完成。您必须手动创建 View 模型的实例并将其公开为父(shell 的) View 模型的属性(或将其设为静态,但这是一种糟糕的方法)。
<Window>
<ContentControl Content="{Binding MenuViewModelInstace}"/>
</Window>
WPF 随后将为您创建 View 以显示 View 模型,但您应该直接在 XAML 标记中定义它,正如我之前提到的。 Prism 在这里帮不了您。
关于c# - 如何使用 MEF 初始化 viewModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28536928/
Glenn Block 和我一直在研究 ViewModel 模式。我们一直在尝试找出与该模式相关的最大痛点,目标是添加框架支持以减轻痛苦。 今晚,格伦发帖,“View Model” – the mov
如果我使用 Views 创建 ViewModel 实例且 ViewModel 没有对 View 的引用的方法,我不知道创建 viewmodel 关系的正确方法是什么。 假设我们有 ChildView
当从缓存中重新加载 ViewModel 时,我需要能够拦截框架并执行重新初始化。由于没有重新创建 ViewModel,我既不能使用 Init()、MvxViewModel.InitFromBundle
我的业务模型(实际上它用于使用 Entity Framework 6 读取数据)看起来像: class Profile : NameDescriptionBase { public virtu
我在swift中玩MVVM遇到了这种情况:我为 tableView 创建了模型,其中包含对象列表和对象计数。有点像 class TableViewViewModel { var count :
我正在研究由以下部分组成的应用程序区域: Explorer - 包含 TreeView PropertyInspector - 包含一个 PropertyGrid 编辑器 - 包含一个 Explore
我正在使用 MVVM-Light,并且我有一个列出了销售人员的 DataGrid 工作。用户可以双击打开一个子窗口,该窗口将在网格上列出他们的销售,用户将能够在该网格下填写一些文本框以添加新的销售。
是否有适当的方法来创建包含 subViewModel 的 C#/WPF ViewModel ? 目标是: 我有一个主窗口。该窗口用于读取/创建图像。窗口上有一个按钮,可以在 2 个 UserContr
首先,如果这很简单,我必须道歉。我对 WPF 和 MVVM 非常陌生,我想确保我没有违反任何 WPF 或 MVVM 概念。此外,对于下面的冗长解释(试图提供所有细节): 我目前正在引用具有所有业务逻辑
我有一个架构问题,以及一个我想提出意见的可能解决方案。 我习惯于 WP7 的 MVVM 架构(尽可能但不幸的是,有时 sdk 似乎朝着相反的方向发展)。 WP7 强制采用 ViewFirst 方法,我
鉴于以下情况: ViewModelA 启动 ViewModelB(当然,通过一个通用 Controller ,它使用 Ioc 和 DI 来解析所需的类型)。 ViewModelB 需要在 ViewMo
在我的 WPF MVVM 应用程序中,使用 Caliburn.Micro,我有一个 ViewModel,CreateServiceViewModel,在单击按钮时,它会在单独的窗口中打开一个 Grid
假设我有一个采用特定 ViewModel 的页面( View ): @model IEnumerable 在这个页面中,我有一个通过另一个 ViewModel(我们称之为 PostModel)发布数据
我有两个相似的 ViewModel,我需要将一个转换为另一个。 这是第一个: using System; using System.Collections.Generic; using System.
我有两个 View 共享来自某个 View 模型的一个可观察集合,但具有不同的 Collection View 参数。在 MVVM Light 中实现它的正确方法是什么?是否支持非静态虚拟机?我如何管
我有 2 个 View 模型 - 主视图模型** 存储 View 模型 StorageViewModel.kt class StorageViewModel @ViewModelInject cons
我有一个 AddressesViewModel 保存用户最喜欢的地址,另一个 SearchViewModel 保存搜索到的地址。当用户搜索地址时,我必须通过检查收藏夹数组来检查该地址是否是收藏夹。正确
首先,我看过this post并没有找到我的问题的答案。 我不确定这是否是汇总 型号 类或聚合 查看型号 类,但这就是我所拥有的: 在我的 WPF(使用 Prism)应用程序中,我有一个 View “
我的 View 中有这些过滤器,它们都会更新 FilterViewModel,然后由它负责过滤数据。其中一个 View ,SearchAddressView 需要 PlacemarkViewModel
依赖的 ViewModel 通过构造函数(IoC 容器)注入(inject)。 示例:ProductSelectionViewModel 使用 ShoppingBasketViewModel。 这是一
我是一名优秀的程序员,十分优秀!