我希望有人能帮助我功成这个简单的WPF MVVM例子,因为我很努力的数据下探到视图模型。
我有一个SQL表温度,其中每个记录都有一个时间标记和一个数字值,例如
LOGTIME --------------温度
2013年1月1日00:00 --60
2013年1月1日00:05 --61.1
2013年1月1日00:10 --61.2
我的WPF查看将有一个开始日期时间和结束日期时间选择器和一个GridView控件允许用户从一个日期范围选择记录,然后在网格中显示它们
我的模型是实体框架,以便在那里我挣扎是什么,我会需要的视图模型,并在那里将LINQ查询到通过用户输入的开始和结束日期时间。 我evetually要图表的数据,并有一定的需求量的(scichart)使用可观察集合的数据。 但我只想得到一个非常simplisitic数据例子来看看数据库的数据是如何在视图模型得到的观察集合结合的观点。 我还使用Telerik的WPF控件我的GridView和我知道他们会做不同的事情。
正如你可以告诉我是一个初学者,并一直在努力在别处找到一个简单的例子(复杂的负荷),否则因此任何帮助是极大的赞赏。
这实际上是一个相当大的问题。 然而,让事情变得简单,并排除设计模式和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>
一VieModel类称为像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
在这里,我嘲笑了一个小班,以复制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
该视图模型基本上暴露了相关的公共属性的查看。 要注意一个重要的事情,就是你必须实现INotifyPropertyChanged接口,提高PropertyChanged事件何时属性已经视图模型中的变化来更新视图。
然后,您需要添加以下到后面新建子代码;
Me.DataContext = New clsMyTemperatureViewModel
这将您的视图的DataContext的设置为新视图模型。
正如我前面提到的,这个例子并不试图涉及任何MVVM框架,也没有使用任何适当的设计模式。
你真的应该使用您的数据存储库模式。 这是这个库,你会把你LINQ到实体代码,只返回一个ObservableCollection您的视图模型内。
您可以创建具有一个解决方案;
- 项目这将容纳您的EF上下文
- 一个项目,数据库系统信息库
- 一个项目的主应用程序这反过来会对文件夹设置为您的看法,视图模型,类行为等。
但是,我希望这个GET的你去!
创建一个视图模型,并让它看起来像这样:
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>
我没有测试过这一点,但它应该给你在正确的方向推。