2014-01-29 394 views
-1

我會先發布我的代碼,然後問我的問題。在MVVM應用程序上數據更改不會持久到實體框架

XAML:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:FootballPool" mc:Ignorable="d" x:Class="MainWindow" 
    xmlns:system="clr-namespace:System;assembly=mscorlib" 
    Title="MainWindow" Height="350" Width="525" Margin="5"> 
    <Window.Resources> 
     <local:MainWindowVM x:Key="ViewModel" /> 
     <ObjectDataProvider x:Key="YearList" 
          ObjectType="{x:Type local:MainWindowVM}" 
          MethodName="YearList" /> 
     <ObjectDataProvider x:Key="WeekList" 
          ObjectType="{x:Type local:MainWindowVM}" 
          MethodName="WeekList"> 
      <ObjectDataProvider.MethodParameters> 
       <system:Int32>0</system:Int32> 
      </ObjectDataProvider.MethodParameters> 
     </ObjectDataProvider> 
    </Window.Resources> 
    <Grid> 
     <TabControl Margin="0,0,0,37"> 
      <TabItem Header="Standings"> 
       <Grid Background="#FFE5E5E5"/> 
      </TabItem> 
      <TabItem Header="Users"> 
       <Grid Background="#FFE5E5E5"> 
        <DataGrid 
         x:Name="dgUsers" 
         DataContext="{Binding Source={StaticResource ViewModel}}" 
         ItemsSource="{Binding Users, Mode=TwoWay}" AutoGenerateColumns="False" 
         IsSynchronizedWithCurrentItem="True" 
         > 
         <DataGrid.Columns> 
          <DataGridTextColumn Binding="{Binding FirstName}" ClipboardContentBinding="{x:Null}" Header="First Name"/> 
          <DataGridTextColumn Binding="{Binding LastName}" ClipboardContentBinding="{x:Null}" Header="Last Name"/> 
          <DataGridTextColumn Binding="{Binding Email}" ClipboardContentBinding="{x:Null}" Header="Email"/> 
          <DataGridTextColumn Binding="{Binding Password}" ClipboardContentBinding="{x:Null}" Header="Password"/> 
         </DataGrid.Columns> 

        </DataGrid> 
       </Grid> 
      </TabItem> 
      <TabItem Header="Weekly Settings"> 
       <Grid Background="#FFE5E5E5"> 
        <Grid x:Name="Grid1" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#FFC8C8C8" Margin="238,27,0,0" DataContext="{Binding SelectedItem, ElementName=listBox}"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="Auto"/> 
          <ColumnDefinition Width="Auto"/> 
         </Grid.ColumnDefinitions> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
         </Grid.RowDefinitions> 
         <Label Content="Year:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/> 
         <TextBox x:Name="Year" Grid.Column="1" HorizontalAlignment="Left" Height="24" Margin="3" Grid.Row="0" Text="{Binding Year, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> 
         <Label Content="Week Number:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="1" VerticalAlignment="Center"/> 
         <TextBox x:Name="WeekNumberTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="1" Grid.Row="1" Text="{Binding WeekNumber, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> 
         <Label Content="Begin Date:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="2" VerticalAlignment="Center"/> 
         <DatePicker x:Name="BeginDateDatePicker" Grid.Column="1" HorizontalAlignment="Left" Margin="3" Grid.Row="2" SelectedDate="{Binding BeginDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center"/> 
         <Label Content="End Date:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="3" VerticalAlignment="Center"/> 
         <DatePicker x:Name="EndDateDatePicker" Grid.Column="1" HorizontalAlignment="Left" Margin="3" Grid.Row="3" SelectedDate="{Binding EndDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center"/> 
         <Label Content="Cost:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="4" VerticalAlignment="Center"/> 
         <TextBox x:Name="CostTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="4" Text="{Binding Cost, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> 

        </Grid> 
        <Button x:Name="btnNewWeek" Content="New Week" HorizontalAlignment="Left" Height="23" Margin="384,192,0,0" VerticalAlignment="Top" Width="75"/> 
        <ComboBox x:Name="cboYear" 
           HorizontalAlignment="Left" Margin="94,14,0,0" 
           VerticalAlignment="Top" Width="56" 
           IsSynchronizedWithCurrentItem="True" 
           ItemsSource="{Binding Mode=OneWay, Source={StaticResource YearList}}"> 
         <ComboBox.SelectedItem> 
          <Binding Source="{StaticResource WeekList}" 
            Path="MethodParameters[0]" 
            BindsDirectlyToSource="True" 
            UpdateSourceTrigger="PropertyChanged" /> 
         </ComboBox.SelectedItem> 
        </ComboBox> 
        <ListBox x:Name="listBox" HorizontalAlignment="Left" Height="136" Margin="95,51,0,0" VerticalAlignment="Top" Width="55" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource WeekList}}" DisplayMemberPath="WeekNumber" /> 
        <Label Content="Year:" HorizontalAlignment="Left" Margin="27,10,0,0" VerticalAlignment="Top"/> 
        <Label Content="Week:" HorizontalAlignment="Left" Margin="27,51,0,0" VerticalAlignment="Top"/> 
       </Grid> 
      </TabItem> 
     </TabControl> 
     <Button Content="Save" HorizontalAlignment="Right" Height="27" Margin="0,0,5,5" VerticalAlignment="Bottom" Width="80" Click="Button_Click"/> 
    </Grid> 
</Window> 

視圖模型:

Imports System.Collections.ObjectModel 
Imports System.ComponentModel 
Imports System.Collections.Specialized 

Public Class MainWindowVM 
    Implements INotifyPropertyChanged 
    Implements INotifyCollectionChanged 

    Dim dbcontext As New FootballPoolEntities 
    Private _Users As ObservableCollection(Of User) 
    Private _Settings As ObservableCollection(Of ScheduleSetting) 
    Public Property Users As ObservableCollection(Of User) 
     Get 
      Return _Users 
     End Get 
     Set(value As ObservableCollection(Of User)) 
      _Users = value 
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Users")) 
     End Set 
    End Property 
    Public Property Settings As ObservableCollection(Of ScheduleSetting) 
     Get 
      Return _Settings 
     End Get 
     Set(value As ObservableCollection(Of ScheduleSetting)) 
      _Settings = value 
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Settings")) 
     End Set 
    End Property 

    Public Sub New() 
     _Users = New ObservableCollection(Of User)(dbcontext.Users.ToList) 
     _Settings = New ObservableCollection(Of ScheduleSetting)(dbcontext.ScheduleSettings.ToList) 
     AddHandler Users.CollectionChanged, AddressOf OnUsersCollectionChanged 
     AddHandler Settings.CollectionChanged, AddressOf OnSettingsCollectionChanged 
    End Sub 

    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged 
    Public Event CollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs) Implements INotifyCollectionChanged.CollectionChanged 

    Private Sub OnUsersCollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs) 
     If e.Action = NotifyCollectionChangedAction.Add Then 
      For Each item In e.NewItems 
       dbcontext.Users.Add(item) 
      Next 
     End If 
     If e.Action = NotifyCollectionChangedAction.Remove Then 
      For Each item In e.OldItems 
       dbcontext.Users.Remove(item) 
      Next 
     End If 
    End Sub 

    Private Sub OnSettingsCollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs) 
     If e.Action = NotifyCollectionChangedAction.Add Then 
      For Each item In e.NewItems 
       dbcontext.ScheduleSettings.Add(item) 
      Next 
     End If 
     If e.Action = NotifyCollectionChangedAction.Remove Then 
      For Each item In e.OldItems 
       dbcontext.ScheduleSettings.Remove(item) 
      Next 
     End If 
    End Sub 

    Public Sub SaveChanges() 
     dbcontext.SaveChanges() 
    End Sub 
    Public Sub NewWeek() 
     Dim newWeek As New ScheduleSetting 
     Settings.Add(newWeek) 
    End Sub 

    Public Function WeekList(SelectedYear As Int32) As ObservableCollection(Of ScheduleSetting) 
     If SelectedYear = 0 Then 
      Return Nothing 
      Exit Function 
     End If 
     Return New ObservableCollection(Of ScheduleSetting)(Settings.Where(Function(c) c.Year = SelectedYear).ToList) 
    End Function 

    Public Function YearList() As List(Of Int32) 
     Return dbcontext.ScheduleSettings _ 
      .Select(Function(x) x.Year) _ 
      .Distinct.ToList() 
    End Function 
End Class 

我遇到的問題是,我的列表框與設置填充通過 「WeekList」 方法和ObjectDataProvider的對象。我的細節網格有它的datacontext綁定到該列表框的SelectedItem。當我對數據進行更改時,執行savechanges時,它們不會保留回實體框架。我是否在綁定中缺少某些東西,我應該如何處理主 - 細節?或者我需要添加ViewModel中的某些東西?

我感謝任何人可以提供幫助。謝謝。

回答

0

那麼我能夠從其他地方收到答案,但是要感謝任何正在嘗試的人。

解決方案是,我需要刪除ObjectDataContext的,而是使用更多的屬性。

我創建了一個SelectedYear屬性作爲整數和WeekList屬性作爲schedulesetting的observable集合。 Selected year屬性被綁定爲我的組合框的selecteditem,而weeklist的getter使用lambda表達式中的selected week屬性返回過濾的星期列表。

我不得不對其進行更改,以便在組合框和列表框中爲虛擬機設置datacontexts。事後看來,這部分應該是顯而易見的。

相關問題