2016-04-29 10 views
0

私はWPFには新しく、現時点ではMVVMに基づくEntity Framework 6(コードファースト)を使用してマスター詳細アプリケーションを構築しています。icollectionviewを使用して項目を追加または削除し、MVVMパターンを使用してEFデータベースに反映する方法

ここにUIがあります。

enter image description here

詳細は、DataGridのマスターデータグリッド---カテゴリー---製品

私が必要とする機能:

  1. 変更、追加、 "カテゴリ" の項目を削除しますか、 「製品」の項目

  2. T 「保存」ボタンをクリックしてデータベースに保存します。

  3. マスターデータグリッドに表示された項目を制御するカテゴリフィルタ。

私はビューモデルでicollectionview "Categrories"にマスターデータグリッドをバインドしています。

<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:WPFwithEFSampleCodeFirst" mc:Ignorable="d" x:Class="WPFwithEFSampleCodeFirst.MainWindow" 
    Title="MainWindow" Height="352.134" Width="585.53" Loaded="Window_Loaded"> 

<Grid Margin="0,0,0,-3"> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="0*"/> 
     <ColumnDefinition Width="77*"/> 
     <ColumnDefinition Width="25*"/> 
    </Grid.ColumnDefinitions> 
    <Button Content="Save" Command="{Binding SaveCmd}" Grid.Column="1" HorizontalAlignment="Left" Margin="425,137,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" Grid.ColumnSpan="2"/> 
    <DataGrid x:Name="MasterGrid" SelectedItem="{Binding SelectedCategory}" ItemsSource="{Binding Categories}" Grid.ColumnSpan="2" AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="32,10,0,0" VerticalAlignment="Top" Height="124" Width="330" > 
     <DataGrid.Columns> 
      <DataGridTextColumn Width="SizeToHeader" Header="Category Id" Binding="{Binding Path = CategoryId}"/> 
      <DataGridTextColumn Width="SizeToHeader" Header="Category Name" Binding="{Binding Path = Name}"/> 
     </DataGrid.Columns> 
    </DataGrid> 

    <DataGrid ItemsSource="{Binding SelectedCategoryProducts}" Grid.ColumnSpan="2" AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="32,153,0,0" VerticalAlignment="Top" Height="146" Width="330"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Binding="{Binding CategoryId}" Header="Category Id" Width="SizeToHeader"/> 
      <DataGridTextColumn Binding="{Binding Name}" Header="Product Name" Width="SizeToHeader"/> 
      <DataGridTextColumn Binding="{Binding ProductId}" Header="Product Id" Width="SizeToHeader"/> 
     </DataGrid.Columns> 
    </DataGrid> 
    <ComboBox ItemsSource ="{Binding DistinctCategoryName }" SelectedItem="{Binding SelectedCategoryName , Mode = TwoWay }" IsSynchronizedWithCurrentItem="True" Grid.Column="1" HorizontalAlignment="Left" Margin="398,37,0,0" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2"/> 
    <Label Content="Category Name filter" Grid.Column="1" HorizontalAlignment="Left" Margin="398,6,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/> 
</Grid> 

のViewModel:

class MainWindowViewModel:INotifyPropertyChanged 
{ 
    ProductContext context = new ProductContext(); 

    public MainWindowViewModel() 
    { 
     IList<Category> categories = GetCategories(); 
     _categoryView = CollectionViewSource.GetDefaultView(categories); 

     DistinctCategoryName = GetDistinctCategoryName(); 
     _saveCmd = new RelayCommand(Save, CanSave); 

    } 

    public IList<Category> GetCategories() 
    { 
     return context.Categories.ToList(); 
    } 

    private ICollectionView _categoryView; 
    public ICollectionView Categories 
    { 
     get { return _categoryView; } 
    } 

    private string _selectedCategoryName; 
    public string SelectedCategoryName 
    { 
     get { return _selectedCategoryName; } 
     set 
     { 
      _selectedCategoryName = value; 

      _categoryView.Filter = new Predicate<object>(GetFilteredView); 
      _categoryView.Refresh(); 

      OnPropertyChanged("SelectedCategoryName"); 
     } 
    } 



    private IList<string> _distinctCategoryName; 

    public IList<string> DistinctCategoryName 
    { 
     get { return _distinctCategoryName; } 
     set 
     { 
      _distinctCategoryName = value; 
      OnPropertyChanged("DistinctCategoryName"); 
     } 

    } 

    private List<string> GetDistinctCategoryName() 
    { 
     List<string> distCateName; 
     List<Category> catelist = context.Categories.ToList(); 
     distCateName = catelist.Select(e => e.Name).Distinct().ToList(); 

     return distCateName; 
    } 


    private ICommand _saveCmd; 
    public ICommand SaveCmd { get { return _saveCmd; } } 
    public void Save(object obj) 
    { 
     foreach (var product in context.Products.Local.ToList()) 
     { 
      if (product.Category == null) 
      { 
       context.Products.Remove(product); 
      } 
     } 


     context.SaveChanges();// What can I do Here to save the category change??? 

     //DistinctCategoryName = GetDistinctCategoryName(); 
    } 

    public bool CanSave(object obj) 
    { 

     return true; 
    } 

    public bool GetFilteredView(object sourceObject) 
    { 
     Category cate = sourceObject as Category; 
     if (cate.Name == _selectedCategoryName) 
     { 
      return true; 
     } 
     return false; 
    } 

    private Category _selectedCategory; 
    public Category SelectedCategory 
    { 
     get { return _selectedCategory; } 
     set 
     { 
      _selectedCategory = value; 
      OnPropertyChanged("SelectedCategory"); 
      OnPropertyChanged("SelectedCategoryProducts"); 
     } 
    } 

    public ObservableCollection<Product> SelectedCategoryProducts 
    { 
     get 
     { 
      if (_selectedCategory == null) return null; 

      return _selectedCategory.Products; 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string propertyName) 
    { 
     //Fire the PropertyChanged event in case somebody subscribed to it 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

問題:私はので、フィルタ機能のマスターデータグリッドへのICollectionViewに結合してい

。 追加(新しい行の追加)または削除(ヒットの削除キー)カテゴリアクションをデータベースに保存することはできません。 (私はそれが実際のソースの代わりにVIEWで作業しているからだと思うので)icollectionviewを通してアイテムを追加/削除し、データベース(ソース)に反映する適切な方法は何ですか? ICollectionViewを使用しないでください。

答えて

0

BindableBaseクラスからviewmodelクラスを継承します。

カテゴリのプライベートメンバーとプロパティを作成します。

private ObservableCollection<DataClass> categories = new ObservableCollection<DataClass>(); 

public ObservableCollection<DataClass> Categories 
{ 
get { return categories; } 
set { SetProperty(ref categories, value); } 
} 

は今カテゴリーにソースをバインドします。新しい項目を追加するたびに、カテゴリが更新されます。 saveコマンドでは、リスト全体または現在選択されている項目をdbに保存できます。つまり、他のビュー/ビューモデルでクラスまたはプロパティのプロパティ変更イベントを取得し、そのイベントを使用してデータをデータベースに保存することができます。

+0

あなたは、ObservableCollection master datagirdをICollectionViewカテゴリの代わりにカテゴリにバインドする必要がありますか? –

+0

ObservableCollectionカテゴリでフィルタ機能を実行するにはどうすればよいですか? –

+0

これを実現するにはLINQを使用できます。 例:list.Where(m => m.SomeDataItem == FilterCondition m).ToList();これにより、条件ごとにフィルタリングされ、リストが表示されます。 – ViVi

関連する問題