2016-06-22 11 views
2

Basis auf this excellent presentation von Laurent Bugnion bei Xamarin Evolve 2014, ich versuche, meine erste UWP/MVVM Light-Anwendung zu erstellen.Mvvm Licht, UWP und Code hinter

habe ich eine sehr einfache Artikel: ObservableObject Klasse mit 2 string Eigenschaften: Référence und Désignation.

Nach Ansicht Modell auf den Artikel Listenansicht zugeordnet ist, habe ich eine Aktion einen neuen Artikel zu erstellen:

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)); 
    } 

hier ist das XAML für meine Artikel Detailansicht:

<!-- 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> 

Meine Problem hier ist, dass ich den DataContext in den Code hinter meiner Seite definieren muss:

Gibt es eine Möglichkeit, die Entwurfszeit DataContext wie im d: DataContext-Teil der Xaml-Seite definiert zu halten und zur Laufzeit den DataContext vom Parameter Navigation abzurufen?

Mein Ziel ist es, die geringere Menge an Code im Code hinter sich zu haben. Also ich möchte auch die Laufzeit DataContext im XAML definieren.

+2

Nur ein Rat von einem anderen französisch Typ: Sie sollten nie akzentuierte Zeichen verwenden in deinen Klassen Mitglieder/Methoden. Verwenden Sie einfach ACSII-Zeichen, um Fehler zu vermeiden. –

+0

Arnaud, wir könnten dies stundenlang diskutieren :) Um es klar zu sagen, ich habe Akzente für mehr als 10 Jahre in C# verwendet.Ich frage meine Entwickler (ok, ich zwinge sie), dies zu tun, weil ich nie irgendwelche Fehler hatte, Visual Studio verwaltet perfekt Unicode-Dateien 2/Es macht den Code viel besser lesbar 3/Ich habe das Gefühl, dass Ihre Idee kommt aus alten Zeitsprachen (ich habe Delphi seit Jahren vor der .Net-Zeit benutzt) –

+1

@JulienFerraro Sie sollten Französisch in irgendeinem Code vermeiden, der, eines Tages, von einem nicht-französischen Sprecher gelesen werden kann. Hier zerstören Sie mindestens zwei [Naiming-Konventionen] (http://mindprod.com/jgloss/unmainnaming.html). Halte es sauber. – aloisdg

Antwort

1

Sie können die Abhängigkeitsinjektion verwenden, um Entwurfs- oder Laufzeitdienst-Instanzen für Ihr Ansichtsmodell zu erstellen. eine Ansicht Modell-Locator verwenden, können Sie etwas tun:

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>(); 
} 

Und in Ihrem App.xaml Sie den Locator

<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> 

registrieren und dann können Sie es in Ihrem XAML wie diese Referenz:

<Page 
... 
DataContext="{Binding ArticleViewModel, Source={StaticResource Locator}}"> 

Sie könnten auch einen Blick auf die Beispielcode nehmen hier https://mvvmlight.codeplex.com/SourceControl/latest#Samples/Flowers/Flowers.Data/ViewModel/ViewModelLocator.cs

+0

Hosney, danke für deine schnelle Antwort. Wie auch immer, meine Frage war nicht genau das. Ich habe ziemlich genau den gleichen Code wie der, den Sie in meiner Lösung zeigen. Bitte werfen Sie einen Blick auf die Flowers.Wp/DetailsPage.xaml im Beispiel. Der DataContext ist für die Entwurfszeit definiert. Der Kontext der Laufzeitdaten ist im nachfolgenden Code definiert. Meine Frage ist: Warum sollten wir den Laufzeitdatenkontext im dahinterliegenden Code definieren? –

+0

@JulienFerraro muss es nicht so sein. Ich habe den DataContext nur in der XAML im obigen Code angegeben. Kein Code dahinter. Der Locator entscheidet anhand der Ausführung der Anwendung oder im Entwurfsmodus, welche Serviceinstanz zurückgegeben werden soll. – H77

+0

Überprüfen Sie Flowers.Wp/MainPage.xaml im Beispiel. Es verwendet das gleiche Konzept. – H77

0

Dazu müssen Sie Ihre eigene Implementierung von NavigationService verwenden. Das Konzept besteht darin, zu Ihrer Seite zu navigieren und Ihr ViewModel gleichzeitig aufzurufen, um Parameter zu verarbeiten und den DataContext festzulegen.

Hier sind zwei Proben dieses Muster:

Verwandte Themen