2014-01-29 1 views
-1

먼저 코드를 게시하고 질문합니다.MVVM 응용 프로그램에서 Entity Framework로 데이터 변경 사항이 지속되지 않습니다.

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를 통해 객체. 내 세부 그리드는 해당 목록 상자의 SelectedItem에 바인딩 된 datacontext 있습니다. 데이터를 변경할 때 savechanges를 수행 할 때 엔티티 프레임 워크로 되돌아 가지 않습니다. 제가 구속력있는 것을 놓치고 있습니까? 마스터 디테일을 다르게 처리해야합니까? 또는 내 ViewModel에 내가 추가해야 할 무언가가 있습니까?

누군가가 제공 할 수있는 도움에 감사드립니다. 감사.

답변

0

다른 곳에서 답을 얻을 수 있었지만 시도해 본 사람에게 감사드립니다.

해결 방법은 ObjectDataContext를 삭제하고 더 많은 속성을 사용해야한다는 것입니다.

정수로 SelectedYear 속성을 만들고 일정 설정의 관찰 가능 수집으로 WeekList 속성을 만들었습니다. 선택한 연도 속성은 내 콤보 상자의 selecteditem으로 바인딩되었고, 주 목록에서는 탬퍼 식에서 선택한 week 속성을 getter로 사용하여 필터링 된 주 목록을 반환했습니다.

datacontexts가 콤보 상자와 VM의 목록 상자에 모두 설정되도록 변경해야했습니다. 뒤늦은 시야에서 그 부분은 분명해야했습니다.

관련 문제