一、准备工作

1.开发工具 Visual Studio 2013

2.安装 Entity Framework 6 Tools for Visual Studio 2012 & 2013 来实现 Code First with Database

工具下载: http://www.microsoft.com/en-us/download/details.aspx?id=40762

3.创建示例数据库 MyShop

USE MyShop
GO CREATE TABLE [dbo].[Categories]
(
[CategoryId] [INT] NOT NULL IDENTITY ,
[Name] [NVARCHAR](MAX) ,
CONSTRAINT [PK_dbo.Categories] PRIMARY KEY ( [CategoryId] )
) CREATE TABLE [dbo].[Products]
(
[ProductId] [INT] NOT NULL
IDENTITY ,
[Name] [NVARCHAR](MAX) ,
[CategoryId] [INT] NOT NULL ,
CONSTRAINT [PK_dbo.Products] PRIMARY KEY ( [ProductId] )
) CREATE INDEX [IX_CategoryId] ON [dbo].[Products]([CategoryId]) ALTER TABLE [dbo].[Products]
ADD CONSTRAINT [FK_dbo.Products_dbo.Categories_CategoryId]
FOREIGN KEY ([CategoryId]) REFERENCES [dbo].[Categories] ([CategoryId])
ON DELETE CASCADE
GO INSERT INTO dbo.Categories ( Name ) VALUES( N'水果' )
INSERT INTO dbo.Categories ( Name ) VALUES( N'肉类' )
GO INSERT INTO dbo.Products ( Name, CategoryId ) VALUES ( N'苹果', 1)
INSERT INTO dbo.Products ( Name, CategoryId ) VALUES ( N'菠萝', 1)
INSERT INTO dbo.Products ( Name, CategoryId ) VALUES ( N'猪肉', 2)
INSERT INTO dbo.Products ( Name, CategoryId ) VALUES ( N'牛肉', 2)
INSERT INTO dbo.Products ( Name, CategoryId ) VALUES ( N'人肉', 2)
GO

二、创建项目 WPFwithEFSample

三、更新 Entity Framework

四、创建Code First with Database

上面的步骤会自动生成实体类,所以需要编译一下,下一步的动作才会显示出需要的对象。

我们看下Code First with Database 工具帮我们生成了什么东东。

生成了3个文件,其中2个实体文件,分别对应数据库里的2张表Category 和 Product。还有一个MyShopContext.cs,这是数据库上下文,操作数据库的时候需要实例化此类。

namespace WPFwithEFSample
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial; public partial class Category
{
public Category()
{
Products = new HashSet<Product>();
} public int CategoryId { get; set; } public string Name { get; set; } public virtual ICollection<Product> Products { get; set; }
}
}

Category.cs

namespace WPFwithEFSample
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial; public partial class Product
{
public int ProductId { get; set; } public string Name { get; set; } public int CategoryId { get; set; } public virtual Category Category { get; set; }
}
}

Product.cs

namespace WPFwithEFSample
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq; public partial class MyShopContext : DbContext
{
public MyShopContext()
: base("name=MyShopContext")
{
} public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Product> Products { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
}

MyShopContext.cs

MyShopContext.cs 代码中的 name=MyShopContext 值来自于配置文件 App.Config中的数据库连接字符串

  <connectionStrings>
<add name="MyShopContext"
connectionString="data source=.;initial catalog=MyShop;user id=sa;password=*******;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>

五、添加数据源,来自对象,也就是刚才用Code First with Database 工具生成的类,并且需要编译一次,否则向导工具发现不了!

调出数据源窗口:视图  ->  其他窗口 ->  数据源

然后点击 数据库窗口的超链接“添加数据源...”

如果没发现Category 和Product 选项,重新编译一下就可以了。

点击完成后,在数据源窗口会出现相关项:

生成的这些项后,我们就可以用鼠标拖到窗口后,就能创建界面控件

如果把Category用鼠标拖到界面就能创建GridView控件等

接下来我们就点击上面第一个Category项直接拖入到 MainWindow.xaml 图形界面,看看会产生什么。(不知道为什么每次都要拖2次才成功,可能是VS2013的bug吧)

拖入完后,会在2处自动添加代码,一个是 MainWindow.xaml , 另一个是 MainWindow.xaml.cs

<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:WPFwithEFSample" mc:Ignorable="d" x:Class="WPFwithEFSample.MainWindow"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Window.Resources>
<CollectionViewSource x:Key="categoryViewSource" d:DesignSource="{d:DesignInstance {x:Type local:Category}, CreateList=True}"/>
</Window.Resources>
<Grid DataContext="{StaticResource categoryViewSource}"> <DataGrid x:Name="categoryDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Margin="10,10,51,195" ItemsSource="{Binding}" EnableRowVirtualization="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn x:Name="categoryIdColumn" Width="SizeToHeader" Header="Category Id" Binding="{Binding CategoryId}"/>
<DataGridTextColumn x:Name="nameColumn" Width="SizeToHeader" Header="Name" Binding="{Binding Name}"/>
</DataGrid.Columns>
</DataGrid> </Grid>
</Window>

MainWindow.xaml

using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace WPFwithEFSample
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
} private void Window_Loaded(object sender, RoutedEventArgs e)
{ System.Windows.Data.CollectionViewSource categoryViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("categoryViewSource")));
// 通过设置 CollectionViewSource.Source 属性加载数据:
// categoryViewSource.Source = [一般数据源]
}
}
}

MainWindow.xaml.cs

接下来我们要分析一下这些自动生成的代码的用意。先看 MainWindow.xaml.cs,它就一条语句,意思是:在MainWindow.xaml 页面找到名为"categoryViewSource" 控件,并把他转换为CollectionViewSource类型。

private void Window_Loaded(object sender, RoutedEventArgs e)
{ System.Windows.Data.CollectionViewSource categoryViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("categoryViewSource")));
// 通过设置 CollectionViewSource.Source 属性加载数据:
// categoryViewSource.Source = [一般数据源]
}

来看下 MainWindow.xaml

共自动生成了3大块代码,和其他的一些属性

明天继续。。。

第一段不知道怎么解释,搜了好多资料都没搜到,大概意思就是定义设计器里的名称空间d.......

第二段在窗体级别中定义资源,资源的内容为数据视图,它是数据源和请求数据源之前的接口,如图:

在CollectionViewSource 这里可以对请求的数据“把把关”(添加条件),做排序等。

最重要的是这个扩展属性 x:Key="categoryViewSource" 。对于窗体上的控件来说,它就是数据源。对于后台代码来说,需要把真正的后台数据交给它。

第三段就没什么好讲的了,就是DataGrid控件的具体细节,不过要注意的是它外层的Grid布局空间的一个属性DataContext="{StaticResource categoryViewSource}"
这个属性把上下文内容定义到这个控件的级别,那么他的子空间都可以共享其数据了。

六、添加管理子表的DataGrid 控件,达到的效果是,当电子表里的记录时,子表里的内容会根据附表中的类别号来检索产品。

我们来看一下代码发生了什么变化,绿色框起来的为新增的,变化的文件只有一个 MainWindow.xaml

第一段绿色框起来的也是定义了一个“视图” ,它的数据类型为Products ,但数据源却是来自于上面那个视图的,也就是父视图

好了,到这里为止基本前台的界面都完成了,下面我们要在后台代码来检索数据,然后付给那个父视图控件。

System.Windows.Data.CollectionViewSource categoryViewSource =
((System.Windows.Data.CollectionViewSource)(this.FindResource("categoryViewSource")));

上面的代码是在我们拖入第一个DataGrid的时候自动创建的,意思是,在资源里找到一个名为categoryViewSource的资源对象,并转化为CollectionViewSource类型,

这样我们就能在后台代码里操作这个对象了。

首先在主窗体类的内部的最上面实例化我们的上下文类,可以把对象 _context看着是一个数据库。

然后再添加加载数据的代码

按F5运行程序,如下,在父表点击不同的记录,在子表里或自动变化。

接下来为程序做点加工,这些也都是在软件中经常要用到的功能。

1、为DataGrid 控件添加行编号,这样就能一眼看出记录数和快速定位行了。

实现很简单,只要添加一个DataGrid 的 LoadingRow 事件即可。添加方法:选择DataGrid控件,然后再在属性窗口的事件标签项里找到 LoadingRow,在输入框中双击,就会跳转到实现代码,然后加入下列代码即可。

private void categoryDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Header = e.Row.GetIndex() + ;
}

下面还要添加几个按钮,来做数据的增删改查(CURD)

为了再在页面条件其他控件,我们必须用布局控件来规划窗体的布局。布局后的全部代码为:

<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" Loaded="Window_Loaded">
<Window.Resources>
<CollectionViewSource x:Key="categoryViewSource" d:DesignSource="{d:DesignInstance {x:Type local:Category}, CreateList=True}"/>
<CollectionViewSource x:Key="categoryProductsViewSource" Source="{Binding Products, Source={StaticResource categoryViewSource}}"/>
</Window.Resources>
<Grid DataContext="{StaticResource categoryViewSource}" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0">
<WrapPanel Orientation="Horizontal">
<Button x:Name="btnAddCategory" Content="Add..." Margin="5,5,0,5" Padding="8,5,8,5" />
<Button x:Name="btnDeleteCategory" Content="Delete..." Margin="5,5,0,5" Padding="8,5,8,5" />
<Button x:Name="btnUpdateCategory" Content="Upate..." Margin="5,5,0,5" Padding="8,5,8,5" />
<Button x:Name="btnSeachCategory" Content="Seach" Margin="5,5,0,5" Padding="8,5,8,5" />
</WrapPanel>
<DataGrid x:Name="categoryDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" ItemsSource="{Binding}"
EnableRowVirtualization="True" AutoGenerateColumns="False" LoadingRow="categoryDataGrid_LoadingRow" CanUserDeleteRows="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn x:Name="categoryIdColumn" Width="SizeToHeader" Header="Category Id" Binding="{Binding CategoryId}"/>
<DataGridTextColumn x:Name="nameColumn" Width="SizeToHeader" Header="Name" Binding="{Binding Name}"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="0">
<WrapPanel Orientation="Horizontal">
<Button x:Name="btnAddProduct" Content="Add..." Margin="5,5,0,5" Padding="8,5,8,5" />
<Button x:Name="btnDeleteProduct" Content="Delete..." Margin="5,5,0,5" Padding="8,5,8,5" />
<Button x:Name="btnUpdateProduct" Content="Upate..." Margin="5,5,0,5" Padding="8,5,8,5" />
<Button x:Name="btnSeachProduct" Content="Seach" Margin="5,5,0,5" Padding="8,5,8,5" />
</WrapPanel>
<DataGrid x:Name="productsDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True"
ItemsSource="{Binding Source={StaticResource categoryProductsViewSource}}"
RowDetailsVisibilityMode="VisibleWhenSelected" LoadingRow="productsDataGrid_LoadingRow">
<DataGrid.Columns>
<DataGridTextColumn x:Name="categoryIdColumn1" Binding="{Binding CategoryId}" Header="Category Id" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="nameColumn1" Binding="{Binding Name}" Header="Name" Width="SizeToHeader"/>
<DataGridTextColumn x:Name="productIdColumn" Binding="{Binding ProductId}" Header="Product Id" Width="SizeToHeader"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
</Window>

MainWindow.xaml

这样看起来还不错!

2个DataGrid还有一个小问题,就是选择一行后,其后有个很长的空白行,看起来很不爽,处理办法是吧最后一列的宽度该为*   ,如:

WPF 数据绑定 使用Code First with Database的更多相关文章

  1. 微软原文翻译:适用于.Net Core的WPF数据绑定概述

    原文链接,大部分是机器翻译,仅做了小部分修改.英.中文对照,看不懂的看英文. Data binding overview in WPF 2019/09/19 Data binding in Windo ...

  2. WPF 数据绑定Binding

    什么是数据绑定? Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简单而一致的方法来显示数据以及与数据交互. 通过数据绑定,您可以对两个不同对象 ...

  3. WPF数据绑定Binding(二)

    WPF数据绑定Binding(二) 1.UI控件直接的数据绑定 UI对象间的绑定,也是最基本的形式,通常是将源对象Source的某个属性值绑定 (拷贝) 到目标对象Destination的某个属性上. ...

  4. WPF——数据绑定(一)什么是数据绑定

    注意:本人初学WPF,文中可能有表达或者技术性问题,欢迎指正!谢谢! 一:什么是数据绑定? “Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简 ...

  5. 剖析WPF数据绑定机制

    引言 WPF框架采取的是MVVM模式,也就是数据驱动UI,UI控件(Controls)被严格地限制在表示层内,不会参与业务逻辑的处理,只是通过数据绑定(Data Binding)简单忠实地表达与之绑定 ...

  6. WPF 10天修炼 第十天- WPF数据绑定

    WPF数据绑定 数据绑定到元素属性是将源对象指定为一个WPF元素,并且源属性是一个依赖属性,依赖属性内置了变更通知.当改变源对象依赖属性值之后,绑定目标可以立即得到更新,开发人员不需要手动编写响应事件 ...

  7. 如何在Code First、Database First和Model First之间选择

    Code First.Database First和Model First基本图解: 1)Database First: 如果数据库已经存在,可以使用VS自动生成数据模型,已经相关的edmx信息 2) ...

  8. C#-WPF数据绑定基础(一)

    前言:WPF数据绑定技术有效的提高了程序的容错率,可以最大程度的保持程序的健壮性,从而降低程序在使用过程中崩掉的可能性. 接下来,我将分享一下我在写测量程序过程中所用到的数据绑定方面的知识 首先,我所 ...

  9. C#WPF数据绑定模板化操作四步走

    前言:WPF数据绑定对于WPF应用程序来说尤为重要,本文将讲述使用MVVM模式进行数据绑定的四步走用法: 具体实例代码如下: 以下代码仅供参考,如有问题请在评论区留言,谢谢 1 第一步:声明一个类用来 ...

随机推荐

  1. kepware http接口 php

    读取某变量的值(HttpRequest <?php $request = new HttpRequest(); $request->setUrl('http://127.0.0.1:393 ...

  2. hdu 4455 Substrings(计数)

    题目链接:hdu 4455 Substrings 题目大意:给出n,然后是n个数a[1] ~ a[n], 然后是q次询问,每次询问给出w, 将数列a[i]分成若干个连续且元素数量为w的集合,计算每个集 ...

  3. Linux命令行获取本机外网IP地址

    问题: 服务器地址为net映射地址,本机ifconfig无法直接获取映射的公网地址. 方法: [root@TiaoBan- nidongde]# curl http://ifconfig.me 50. ...

  4. vlookup返回多个结果

    http://www.360doc.com/content/12/1021/15/7665211_242782107.shtml =IFERROR(VLOOKUP(D2&ROW(A1),IF( ...

  5. kafka各个版本特点介绍和总结

    kafka各个版本特点介绍和总结 1.1 kafka的功能特点: 分布式消息队列 消息队列的数据模型, 形成流式数据. 提供Pub/Sub方式的海量消息处理.以高容错的方式存储海量数据流.保证数据流的 ...

  6. 【推荐】介绍两款Windows资源管理器,Q-Dir 与 FreeCommander XE(比TotalCommander更易用的免费资源管理器)

    你是否也像我一样,随着硬盘.文件数量的增加,而感到对于文件的管理越来越乏力. 于是我试用了传说中的各种软件,包括各种Explorer外壳,或者第三方资源管理器. 最后我确定下来经常使用,并推荐给您的是 ...

  7. 【BZOJ2328】 [HNOI2011]赛车游戏

    BZOJ2328 [HNOI2011]赛车游戏 前言 这道题目我真的佛了,卡精度+卡时间这就是下一个聊天鬼才. Solution 首先可以二分出最大速度,然后考虑下坡的话可能有更好的解,然后这样子算一 ...

  8. 201621123018《Java程序设计》第7周学习报告

    1. 本周学习总结 1.1 思维导图:Java图形界面总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 事件.事件源. 事件监听器.事件处理方法 1.2 任 ...

  9. 关于GROUP BY和聚合函数

    可以这样去理解group by和聚合函数 转自 http://www.cnblogs.com/wiseblog/articles/4475936.html 写在前面的话:用了好久group by,今天 ...

  10. soap注入某sql2008服务器结合msf进行提权

    原文作者:陈小兵 在实际成功渗透过程中,漏洞的利用都是多个技术的融合,最新技术的实践,本次渗透利用sqlmap来确认注入点,通过sqlmap来获取webshell,结合msf来进行ms16-075的提 ...