我希望有人可以帮助我实现这个简单的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控件,我知道他们可能会做不同的事情。
正如你所知,我是一个完全的初学者,并且努力在任何地方找到一个简单的例子(很多复杂的例子),所以任何帮助都非常感激。
答案 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。
您将创建一个具有;
的解决方案但是,我希望你能得到它!
答案 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>
我没有对此进行过测试,但它应该会给你一个正确的方向。