WPFwithEFSample

WPF with EF sample

根據 Data Binding with WPF 這篇文章,加以練習,完成WPFwithEFSample方案。

利用 ADO.NET Enitty Framework(database first),Prism,WPF data binding,完成資料新增、移除、 修改、讀取等動作。

資料庫用Sql express,實際上可以用localDB或Sql Compact. ## 實作

MainWindowViewModel.cs
    public class MainWindowViewModel : BindableBase
    {
        private ProductContext _context = new ProductContext();
        public MainWindowViewModel()
        {
            _context.Categories.Load();
            _Source = _context.Categories.Local;
            this.SaveCommand = new DelegateCommand(Save);
        }
        ~MainWindowViewModel()
        {
            _context.Dispose();
        }
        private ObservableCollection _Source;
        public ObservableCollection Source
        {
            get { return _Source; }
            set { SetProperty(ref _Source, value); }
        }
        public DelegateCommand SaveCommand { get; private set; }
        public void Save()
        {
            foreach (var product in _context.Products.Local.ToList())
            {
                if (product.Category == null)
                {
                    _context.Products.Remove(product);
                }
            }
            _context.SaveChanges();
            // Refresh the grids so the database generated values show up.
            // use following two lines to let datagrids rebind
            Source = null;
            Source= _context.Categories.Local;
        }
    }
MainWindow.xaml.cs
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }
MainWindow.xaml
<Window x:Class="WPFwithEFSample.MainWindow"
        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:WPFwithEFSample"
        mc:Ignorable="d"
        Title="MainWindow" >
    <Grid  >
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True"
                  ItemsSource="{Binding Source}"
                  RowDetailsVisibilityMode="VisibleWhenSelected"
                  IsSynchronizedWithCurrentItem="True"
                  >
            <DataGrid.Columns>
                <DataGridTextColumn  Binding="{Binding CategoryId}" Header="Category Id" />
                <DataGridTextColumn  Binding="{Binding Name}" Header="Name" />
            </DataGrid.Columns>
        </DataGrid>
        <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True"
                  ItemsSource="{Binding Source/Products}" Grid.Row="1"
                  RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridTextColumn  Binding="{Binding CategoryId}" Header="Category Id" />
                <DataGridTextColumn  Binding="{Binding Name}" Header="Name" />
                <DataGridTextColumn  Binding="{Binding ProductId}" Header="Product Id" />
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="buttonSave" Grid.Row="2" Content="Save" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="75"   Command="{Binding SaveCommand}"/>
    </Grid>
</Window>
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <connectionStrings>
    <add name="ProductContext" connectionString="metadata=res://*/ProductModel.csdl|res://*/ProductModel.ssdl|res://*/ProductModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\sqlexpress;initial catalog=Products;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>

TODO

MainWindowsViewModel裡的下面兩行,用來促使DataGrid內容的更新, 應有改進空間

    Source = null;
    Source= _context.Categories.Local;

似乎可以用CollectionView.Refresh()來取代Source=null;Source= _context.Categories.Local;這兩個敘述。

Refresh DataGrid after item property change 裡Nitin Joshi提到:

Reloading the DataGrid will be an expensive operation if you have huge set of records. e.g. if you have a table with 1 Cr records and if you made changes in a single field in a record, it will be updated in the db and then if you want to reload the DataGrid for this small change you will have to probably fetch all records and bind the record set with the DataGrid again. This operation will take huge time and user will have to wait unnecessarily.

這是用Refrfesh()的缺點嗎?

Share this

Previous
Next Post »

技術提供:Blogger.