2013-01-02 7 views
3

J'espérais que quelqu'un puisse m'aider à obtenir cet exemple WPF MVVM simple alors que j'ai du mal à mettre les données dans le modèle de vue.WPF EF MVVM Exemple simple

J'ai une table SQL Températures où chaque enregistrement a un horodatage, puis une valeur numérique, par exemple.

LogTime -------------- Température
01/01/2013 00:00 --60
01/01/2013 00:05 --61.1
01/01/2013 00:10 --61.2

Mon WPF Voir aurait un datetime de début et sélecteur de datetime d'extrémité et un gridview permet à l'utilisateur de sélectionner des enregistrements à partir d'une plage de dates, puis les afficher dans la grille

Mon Le modèle est le cadre d'entité donc où je suis en difficulté est ce dont j'ai besoin pour le modèle de vue et où irait la requête linq pour passer l'utilisateur entré début et fin datetime. Je vais probablement cartographier les données et il y a un besoin précis (scichart) d'utiliser une collection observable pour les données. Mais je voulais juste obtenir un exemple de données très simpliste pour voir comment les données de la base de données sont obtenues dans le ViewModel en tant que collection observable pour la liaison à la vue. J'utilise également les contrôles Telerik WPF pour mon GridView et je sais qu'ils peuvent faire les choses différemment. Comme vous pouvez le voir, je suis un débutant complet et j'ai eu du mal à trouver un exemple simple n'importe où (beaucoup de complexes) sinon toute aide est grandement appréciée.

Répondre

2

Il s'agit en fait d'un sujet assez vaste. Cependant, pour garder les choses simples, et exclure les modèles de conception et MVVM Frameworks pour l'instant ...

Vous auriez besoin de créer;

A WPF XAML Voir ayant:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="728" Width="772"> 
    <Grid> 
     <DataGrid AutoGenerateColumns="True" ItemsSource="{Binding MyDataGridDataSource}" HorizontalAlignment="Center" Margin="0,88,0,0" VerticalAlignment="Top" Height="286" Width="584"/> 
     <Grid Margin="0,403,0,0" VerticalAlignment="Top" HorizontalAlignment="Center" > 
      <Grid.RowDefinitions> 
       <RowDefinition></RowDefinition> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition></ColumnDefinition> 
       <ColumnDefinition></ColumnDefinition> 
       <ColumnDefinition></ColumnDefinition> 
       <ColumnDefinition></ColumnDefinition> 
      </Grid.ColumnDefinitions> 
      <Label Content="Start Date:" HorizontalAlignment="Left" Margin="10,8,0,0" VerticalAlignment="Top"/> 
      <DatePicker SelectedDate="{Binding StartDate}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.Column="1"/> 
      <Label Content="End Date:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.Column="2"/> 
      <DatePicker SelectedDate="{Binding EndDate}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.Column="3"/> 
     </Grid> 

    </Grid> 
</Window> 

Une VieModel classe appelée quelque chose comme clsMyTemperatureViewModel:

Imports System.Collections.ObjectModel 
Imports System.ComponentModel 

''' <summary> 
''' Only for Simulating the EF Context! 
''' </summary> 
''' <remarks></remarks> 
Public Class TableTemperatures 

    Public Property LogTime As Date 
    Public Property Temperature As Double 

End Class 


Public Class clsMyTemperatureViewModel : Implements INotifyPropertyChanged 

    Private _ListOfTemperatures As ObservableCollection(Of TableTemperatures) 

    Private _MyDataGridDataSource As ObservableCollection(Of TableTemperatures) 
    Public Property MyDataGridDataSource As ObservableCollection(Of TableTemperatures) 
     Get 
      Return _MyDataGridDataSource 
     End Get 
     Set(value As ObservableCollection(Of TableTemperatures)) 
      _MyDataGridDataSource = value 
      OnPropertyChanged("MyDataGridDataSource") 
     End Set 
    End Property 

    Private _StartDate As Date 
    Public Property StartDate As Date 
     Get 
      Return _StartDate 
     End Get 
     Set(value As Date) 
      If _StartDate <> value Then 
       _StartDate = value 
       OnPropertyChanged("StartDate") 
       GetResults() 
      End If 
     End Set 
    End Property 

    Private _EndDate As Date 
    Public Property EndDate As Date 
     Get 
      Return _EndDate 
     End Get 
     Set(value As Date) 
      If _EndDate <> value Then 
       _EndDate = value 
       OnPropertyChanged("EndDate") 
       GetResults() 
      End If 
     End Set 
    End Property 

    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged 
    Public Sub OnPropertyChanged(ByVal PropertyChangeName As String) 

     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyChangeName)) 
    End Sub 

    Public Sub GetResults() 

     Dim query = From TemperatureList In _ListOfTemperatures 
        Where TemperatureList.LogTime >= StartDate 
        Where TemperatureList.LogTime <= EndDate 
        Select TemperatureList 

     MyDataGridDataSource = New ObservableCollection(Of TableTemperatures)(query) 

    End Sub 

    Public Sub New() 

     ' 
     ' Only for Simulating the EF Context! 
     ' 
     _ListOfTemperatures = New ObservableCollection(Of TableTemperatures) 
     _ListOfTemperatures.Add(New TableTemperatures With {.LogTime = New Date(2012, 9, 1), .Temperature = 14}) 
     _ListOfTemperatures.Add(New TableTemperatures With {.LogTime = New Date(2012, 10, 2), .Temperature = 15}) 
     _ListOfTemperatures.Add(New TableTemperatures With {.LogTime = New Date(2012, 11, 3), .Temperature = 16}) 
     _ListOfTemperatures.Add(New TableTemperatures With {.LogTime = New Date(2012, 12, 4), .Temperature = 17}) 
     _ListOfTemperatures.Add(New TableTemperatures With {.LogTime = New Date(2013, 1, 5), .Temperature = 18}) 

     StartDate = New Date(2011, 1, 1) 
     EndDate = New Date(2014, 1, 1) 

     GetResults() 

    End Sub 
End Class 

Ici, j'ai raillé une petite classe pour reproduire votre contexte EF . Vous devrez toutefois référencer votre contexte EF plutôt que ma collection _ListOfTemperatures. Ce serait quelque chose comme; Le ViewModel expose fondamentalement les propriétés publiques pertinentes à la vue. Une chose importante à noter est que vous devez implémenter l'interface INotifyPropertyChanged et générer l'événement PropertyChanged pour que la vue se mette à jour lorsque les propriétés ont été modifiées dans ViewModel.

Vous devez ensuite ajouter ce qui suit à votre code derrière New Sub;

Me.DataContext = New clsMyTemperatureViewModel 

Cela définira le DataContext de votre vue sur le nouveau ViewModel.

Comme je l'ai mentionné précédemment, cet exemple n'essaie pas d'impliquer des Frameworks MVVM, ni d'utiliser des Patterns de conception appropriés.

Vous devriez vraiment utiliser le modèle de référentiel pour vos données.C'est dans ce Repository que vous placez votre code Linq to Entities, renvoyant uniquement une ObservableCollection à votre ViewModel.

Vous devez créer une solution ayant;

  • Un projet qui abritera votre EF Contexte
  • Un projet pour Référentiels Base de données
  • Un projet pour votre application principale qui aurait à son tour la configuration des dossiers pour vos vues, modèles de vue, classes, Behaviors etc.

Cependant, j'espère que ça vous va!

+0

Merci pour cela, C'est exactement ce que je cherchais –

+0

Content que je puisse vous aider! – PGallagher

1

Créer une vue-modèle et lui donner l'aspect quelque chose comme ceci:

public class YourViewModel: INotifyPropertyChanged 
{ 

private ObservableCollection<YourModel> _yourModels; 
public ObservableCollection<YourModel> YourModels 
    { 
    get { return _yourModels; } 
    set 
    { 
    _yourModels= value; 
    RaisePropertyChanged(() => this.YourModels); 
    } 
    } 

private DateTime _startTime; 
public DateTime StartTime 
    { 
    get { return _startTime; } 
    set 
    { 
    if (value == _startTime) return; 
    _startTime= value; 
    RaisePropertyChanged(() => this.StartTime); 
    } 
    } 

private DateTime _endTime; 
public DateTime SendTime 
    { 
    get { return _endTime; } 
    set 
    { 
    if (value == _endTime) return; 
    _endTime= value; 
    RaisePropertyChanged(() => this.SendTime); 
    } 
    } 

public YourViewModel() 
{ 
YourModels = new ObservableCollection<YourModel>(); 

// 
// You'll need to load your data into the ObservableCollection 
// 

} 
} 

maintenant à votre avis, vous devez lier aux propriétés et collection. Quelque chose comme ceci:

<DatePicker x:Name="startDate" SelectedDate="{Binding Path=StartDate}"></DatePicker> 
<DatePicker x:Name="endDate" SelectedDate="{Binding Path=EndDate}"></DatePicker> 

<ListView ItemsSource="{Binding Path=YourModels}"> 
    <ListView.View> 
     <GridView> 
     <GridViewColumn Header="YourProperty" DisplayMemberBinding="{Binding  Path=YourProperty}" /> 
     </GridView> 
    </ListView.View> 
</ListView> 

Je n'ai pas testé cela, mais il devrait vous donner une poussée dans la bonne direction.

+0

Merci pour l'information c'est exactement ce que je cherchais. Juste une chose de plus. Quelle serait la meilleure méthode pour charger les données dans la collection Observable? Serait-ce une requête linq et une boucle à travers les résultats et ajouter chaque enregistrement? –

+0

@ColinWright ... Vous pouvez obtenir vos nombreuses façons et une était une requête linq. Il n'est pas nécessaire de faire une boucle sur les résultats, il suffit de renvoyer un IEnumerable et de le définir dans votre collection. Je vous recommande de créer une classe d'accès aux données qui gère votre interaction de données. –