我是 PRISM 新手,正在尝试一些东西。我在 MVVM 方面遇到了一些困难。
将 View 与 View 模型“连接”的方式很清楚:
通过统一注入(inject),或
手动设置数据上下文(ServiceLocator)
如果我向区域添加 View ( View 模型是自动创建的),一切都会正常工作。但这不是用例。
让我们看一下示例:
public class MyViewModel : NotificationObject
{
public ObservableCollection<AnotherViewModel> OrderModel { get; private set; }
}
我必须创建 View 模型并将它们添加到集合中。该 View 模型必须在某个区域(OrderRegion)中显示(AnotherView)。我的问题是,当我向区域添加 View 模型时,如何实现现在创建 View 。该区域是一个TabControl,因此可能需要显示不同的 View 。
我已经查看了 PRISM 快速入门和 StockTrader 示例。我正在寻找的内容非常类似于
virtual protected void StartOrder(string tickerSymbol, TransactionType transactionType)
{
if (String.IsNullOrEmpty(tickerSymbol))
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.StringCannotBeNullOrEmpty, "tickerSymbol"));
}
this.ShowOrdersView();
IRegion ordersRegion = _regionManager.Regions[RegionNames.OrdersRegion];
var orderCompositeViewModel = ServiceLocator.Current.GetInstance<IOrderCompositeViewModel>();
orderCompositeViewModel.TransactionInfo = new TransactionInfo(tickerSymbol, transactionType);
orderCompositeViewModel.CloseViewRequested += delegate
{
OrderModels.Remove(orderCompositeViewModel);
commandProxy.SubmitAllOrdersCommand.UnregisterCommand(orderCompositeViewModel.SubmitCommand);
commandProxy.CancelAllOrdersCommand.UnregisterCommand(orderCompositeViewModel.CancelCommand);
commandProxy.SubmitOrderCommand.UnregisterCommand(orderCompositeViewModel.SubmitCommand);
commandProxy.CancelOrderCommand.UnregisterCommand(orderCompositeViewModel.CancelCommand);
ordersRegion.Remove(orderCompositeViewModel);
if (ordersRegion.Views.Count() == 0)
{
this.RemoveOrdersView();
}
};
ordersRegion.Add(orderCompositeViewModel);
OrderModels.Add(orderCompositeViewModel);
commandProxy.SubmitAllOrdersCommand.RegisterCommand(orderCompositeViewModel.SubmitCommand);
commandProxy.CancelAllOrdersCommand.RegisterCommand(orderCompositeViewModel.CancelCommand);
commandProxy.SubmitOrderCommand.RegisterCommand(orderCompositeViewModel.SubmitCommand);
commandProxy.CancelOrderCommand.RegisterCommand(orderCompositeViewModel.CancelCommand);
ordersRegion.Activate(orderCompositeViewModel);
}
View 模型在代码内部创建并添加到区域中。整个类型regstring是通过“ViewExportAttribute”发生的,因此它使得理解其背后的模式变得更加困难。
编辑:
我找到了一种手动执行此操作的方法,但它不是很好:
var view = (FrameworkElement) ServiceLocator.Current.GetInstance<AnotherView>();
var model = ServiceLocator.Current.GetInstance<AnotherViewModel>();
view.DataContext = model;
regionManager.Regions["OrderRegion"].Add(view, null, true);
regionManager.Regions["OrderRegion"].Activate(view);
罗马
编辑2:
嗨,抱歉,可能是我说得不够清楚。
我的目标是创建一个 View 模型,然后像上面 StockTrader 的示例一样配置它:订阅事件、命令等。之后我想将此 View 模型添加到该区域,这样就可以被显示。该区域可能是一个选项卡控件,其中显示具有不同 View 模型的不同 View 。 顺序是:
- 在 Controller 类中创建 View 模型
- 配置 View 模型
- 将 View 模型添加到 Controller 内的本地集合
- 将 View 模型添加到区域
我正在寻找的缺失部分是如何实现它,即使用绑定(bind)等所有内容“自动”创建 View 。我在本文中找到了一种方法( http://www.codeproject.com/Articles/229931/Understand-MVVM-Using-PRISM-by-Hello-World-Silverl )。我必须为 View 和 View 模型创建自己的接口(interface)(IAnotherViewModel、IAnotherView)。
另一种方法可以在这里找到:http://paulstovell.com/blog/viewmodel-first-prism
最佳答案
是否有任何理由不为此使用隐式DataTemplates
?
它们是定义 DataType
属性的 DataTemplates
,但不是 Key
属性,并且在 WPF 尝试绘制对象时使用它们指定数据类型的
例如,
<TabControl ItemsSource="{Binding MyViewModelCollection}"
SelectedItem="{Binding SelectedViewModel}">
<!-- This could also go elsewhere, like Application.Resources -->
<TabControl.Resources>
<DataTemplate DataType="{x:Type local:ViewModelA}">
<local:ViewA />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<local:ViewB />
</DataTemplate>
</TabControl.Resources>
</TabControl>
如果 TabControl
正在显示 ViewModelA
类型的对象,它将使用 ViewA
绘制它,如果它显示 ViewModelB
,它将使用 ViewB
关于c# - PRISM:如何将 View 模型添加到区域并自动创建 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15924930/