WPF MVVM EF简单示例

时间:2013-01-02 15:08:51

标签: wpf mvvm

我希望有人可以帮助我实现这个简单的WPF MVVM示例,因为我正在努力将数据转换为视图模型。

我有一个SQL表温度,其中每个记录都有一个时间戳,然后是一个数值,例如

LOGTIME --------------温度
01/01/2013 00:00 --60
01/01/2013 00:05 - 61.1
01/01/2013 00:10 --61.2

我的WPF视图将具有开始日期时间和结束日期时间选择器,并且gridview允许用户从日期范围中选择记录,然后在网格中显示它们

我的模型是实体框架,因此我正在努力的是视图模型需要什么以及linq查询将在何处传递用户输入的开始和结束日期时间。我常常会对数据进行绘制,并且对数据使用Observable Collection有明确的要求(scichart)。但我只想获得一个非常简单的数据示例,以查看如何在ViewModel中获取数据库数据作为Observable Collection以绑定到视图。我也在为GridView使用Telerik WPF控件,我知道他们可能会做不同的事情。

正如你所知,我是一个完全的初学者,并且努力在任何地方找到一个简单的例子(很多复杂的例子),所以任何帮助都非常感激。

2 个答案:

答案 0 :(得分:2)

这实际上是一个很大的主题。但是,为了简单起见,现在排除设计模式和MVVM框架......

您需要创建;

WPF XAML视图:

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

名为clsMyTemperatureViewModel的VieModel类:

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

这里我模拟了一个小类来复制你的EF上下文。但是,您需要引用EF Context而不是我的_ListOfTemperatures集合。这就像是;

    Public Sub GetResults()

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

        MyDataGridDataSource = New ObservableCollection(Of TableTemperatures)(query)

    End Sub

ViewModel基本上将相关的公共属性公开给View。需要注意的一件重要事情是,必须实现INotifyPropertyChanged接口,并在ViewModel中更改属性时提升视图的PropertyChanged事件以进行更新。

然后,您需要将以下内容添加到New Sub后面的代码中;

Me.DataContext = New clsMyTemperatureViewModel

这会将View的DataContext设置为新的ViewModel。

正如我之前提到的,此示例不会尝试涉及任何MVVM框架,也不会使用任何适当的设计模式。

您应该真正使用存储库模式来处理数据。在此存储库中,您可以将Linq置于实体代码中,仅向ViewModel返回ObservableCollection。

您将创建一个具有;

的解决方案
  • 一个容纳你的EF背景的项目
  • 数据库存储库项目
  • 您的主应用程序的项目,该项目将为您的视图,视图模型,类,行为等设置文件夹。

但是,我希望你能得到它!

答案 1 :(得分:1)

创建一个视图模型,看起来像这样:

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

}
}

现在在您的视图中,您需要绑定到属性和集合。像这样:

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

我没有对此进行过测试,但它应该会给你一个正确的方向。