我正在尝试MVVM模式,特别是我试图确定我将如何使用包含视图(和视图模型)的单独类库。在网上看起来,这似乎是以棱镜和MEF的不同方式完成的,而这可能就是我最终会做的事情。但是,最初我正在使用John Papa created 。
的ServiceLocator示例在该示例中,ViewModelLocator的位置在app.xaml中定义为静态资源:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:MVVMLib="clr-namespace:MVVMLib;assembly=MVVMLib"
x:Class="VMLocatorDemo.App">
<Application.Resources>
<MVVMLib:ViewModelLocator x:Key="VMLocator"/>
<MVVMLib:IndexerConverter x:Key="VMIndexerConverter" />
</Application.Resources>
</Application>
因为view.xaml在同一个项目中,所以它可以引用定位器,一切都很好:
<Grid x:Name="LayoutRoot" Background="White"
DataContext="{Binding Source={StaticResource VMLocator}, Converter={StaticResource VMIndexerConverter}, ConverterParameter=MainPageViewModel}">
<TextBlock Text="{Binding Path=CompanyName}"/>
</Grid>
但是,对于单独的类库,我不能这样做,因为view.xaml不知道定位器位于何处。我需要将定义保留在xaml中,以便我可以继续使用不同的运行时/设计时视图模型。
我想我的问题是,如何在类库中定义Locator类,或者,这正是为什么需要MEF和/或棱镜等其他工具的原因?
非常感谢
杰森
答案 0 :(得分:0)
这是一个使用行为,并默认使用约定来查找视图。我们有服务定位器,但我想可以改进,不依赖于这个静态类
public class ViewModelLocatingBehavior : Behavior<FrameworkElement>
{
#region Overrides
protected override void OnAttached()
{
base.OnAttached();
var viewType = AssociatedObject.GetType();
var viewName = viewType.Name;
var viewModelName = viewName.EndsWith("View")
? viewName + "Model"
: viewName + "ViewModel";
AssociatedObject.DataContext = ServiceLocator.Current.GetInstance<object>(viewModelName);
}
protected override void OnDetaching()
{
base.OnDetaching();
}
#endregion
}
在XAML中
<i:Interaction.Behaviors>
<u:ViewModelLocatingBehavior/>
</i:Interaction.Behaviors>