基于2014年Xamarin Evolve的Laurent Bugnion的this excellent presentation,我正在尝试创建我的第一个UWP / MVVM Light应用程序。
我创建了一个非常简单的文章:ObservableObject 类,其中包含2个字符串属性:Référence和Désignation。
在与文章列表视图关联的视图模型中,我有一个创建新文章的操作:
public ArticlesViewModel(IArticleService dataService, INavigationService navigationService)
{
ArticleService = dataService;
NavigationService = navigationService;
CréeArticleCommand = new RelayCommand(CréeArticle);
}
public RelayCommand CréeArticleCommand { get; private set; }
private void CréeArticle()
{
if (!CréeArticleCommand.CanExecute(null))
return;
NavigationService.NavigateTo(ViewModelLocator.ArticleDetail_Key,
new ArticleViewModel(new Article(),
ArticleService,
NavigationService));
}
这是我的文章详细信息视图的XAML:
<!-- language: xaml -->
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UniversalTest1.UWP.Articles"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Editors="using:DevExpress.UI.Xaml.Editors"
x:Class="UniversalTest1.UWP.Articles.Article_Detail"
mc:Ignorable="d"
xmlns:vm="clr-namespace:UniversalTest1.Data.ViewModels.Articles;assembly=UniversalTest1.Data"
d:DataContext="{d:DesignInstance Type=vm:ArticleViewModel, IsDesignTimeCreatable=True}">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Text="Référence :" HorizontalAlignment="Left" Margin="24,15,0,0" VerticalAlignment="Top"/>
<TextBlock Text="Désignation :" HorizontalAlignment="Left" Margin="10,52,0,0" VerticalAlignment="Top"/>
<Editors:TextEdit Text="{Binding Article.Référence, Mode=TwoWay}" HorizontalAlignment="Left" Margin="100,8,0,0" VerticalAlignment="Top" Width="300"/>
<Editors:TextEdit Text="{Binding Article.Désignation, Mode=TwoWay}" HorizontalAlignment="Left" Margin="100,45,0,0" VerticalAlignment="Top" Width="500"/>
<Button Content="Sauver" Command="{Binding SauverCommand}" HorizontalAlignment="Left" Margin="102,84,0,0" VerticalAlignment="Top"/>
</Grid>
</Page>
我的问题是我必须在我的页面后面的代码中定义DataContext:
public sealed partial class Article_Detail : Page
{
public Article_Detail()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
DataContext = (ArticleViewModel)e.Parameter;
}
}
有没有办法让设计时间DataContext保持在Xaml页面的d:DataContext部分中定义,并且在运行时,从Navigation参数中获取DataContext?
我的目标是让代码背后的代码更少。所以我想在XAML中定义运行时DataContext。
答案 0 :(得分:1)
您可以使用依赖项注入为viewmodel创建设计或运行时服务实例。使用视图模型定位器,您可以执行以下操作:
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
if (!SimpleIoc.Default.IsRegistered<IArticleService>())
{
SimpleIoc.Default.Register<IArticleService, DesignArticleService>();
}
}
else
{
if (!SimpleIoc.Default.IsRegistered<IArticleService>())
{
SimpleIoc.Default.Register<IArticleService, ArticleService>();
}
}
SimpleIoc.Default.Register<ArticleViewModel>();
}
public ArticleViewModel ArticleViewModel => ServiceLocator.Current.GetInstance<ArticleViewModel>();
}
在App.xaml中注册定位器
<Application
x:Class="UniversalTest1.App" // your namespace
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModel="using:UniversalTest1.Data.ViewModels"> // your namespace
<Application.Resources>
<ResourceDictionary>
<viewModel:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Application.Resources>
</Application>
然后你可以在你的xaml中引用它:
<Page
...
DataContext="{Binding ArticleViewModel, Source={StaticResource Locator}}">
您还可以在此处查看示例代码https://mvvmlight.codeplex.com/SourceControl/latest#Samples/Flowers/Flowers.Data/ViewModel/ViewModelLocator.cs
答案 1 :(得分:0)
为此,您需要使用自己的NavigationService
实现。这个概念是导航到您的页面并同时调用 ViewModel 来处理参数并设置 DataContext 。
以下是此模式的两个示例: