3

我希望有人可以帮助我完成这个简单的 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 视图将有一个开始日期时间和结束日期时间选择器和一个网格视图,允许用户从日期范围中选择记录,然后在网格中显示它们

我的模型是实体框架,所以我正在苦苦挣扎的是视图模型需要什么,以及 linq 查询将在哪里传递用户输入的开始和结束日期时间。我最终要绘制数据图表,并且有明确的要求(scichart)为数据使用可观察的集合。但是我只是想获得一个非常简单的数据示例,以了解如何在 ViewModel 中将数据库数据作为 Observable Collection 获取以绑定到视图。我还在为我的 GridView 使用 Telerik WPF 控件,我知道他们可能会做不同的事情。

正如你所知道的那样,我是一个完整的初学者,并且一直在努力在任何地方找到一个简单的例子(大量复杂的例子),所以非常感谢任何帮助。

4

2 回答 2

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 上下文而不是我的 _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 基本上将相关的公共属性暴露给视图。需要注意的一件重要事情是,您必须实现 INotifyPropertyChanged 接口,并引发 PropertyChanged 事件以在 ViewModel 中的属性发生更改时更新视图。

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

Me.DataContext = New clsMyTemperatureViewModel

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

正如我之前提到的,这个例子没有尝试涉及任何 MVVM 框架,也没有使用任何适当的设计模式。

你真的应该为你的数据使用存储库模式。在这个存储库中,您可以放置​​ Linq to Entities 代码,只返回一个 ObservableCollection 给您的 ViewModel。

您将创建一个具有;

  • 一个可以容纳您的 EF 上下文的项目
  • 数据库存储库项目
  • 您的主应用程序的项目,该项目反过来将为您的视图、视图模型、类、行为等设置文件夹。

但是,我希望这能让你继续前进!

于 2013-01-02T16:51:56.207 回答
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>

我还没有测试过这个,但它应该会给你一个正确的方向。

于 2013-01-02T16:56:44.953 回答