---------------------- ASP.Net+Unity開發、 .Net教育訓練、期待與您交流! ----------------------詳細請檢視: www.itheima.com
實作一個可以動态的進行省市縣查詢的程式
一 基本原理: 通過ADO.NET技術查詢資料庫, 并綁定到WPF控件中, 進而實作動态的省市縣查詢.
二 實作技術:
ADO.NET
資料綁定
三 實作步驟:
①首先進行資料庫建立, 在網上下載下傳一個省市縣的資料庫腳本. 部分内容如下圖:
以上腳本建立了一個名叫AreaFull的表, 表中存儲了個省市的資訊.
AreaId----------表示該區域的Id
AreaName----表示該區域的名稱
AreaPid--------表示該區域的直屬上級區域
② 建立了資料庫後, 在vs中使用ADO.NET技術來使用它.
先在App.Config中定義連接配接字元串
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings>
<add name="dbConn" connectionString="Data Source=.; Initial Catalog=MyTest; User ID=sa; Password=123456"/>
</connectionStrings>
</configuration>
定義完之後不能忘了添加引用System.Configuration
然後建立SqlHelper類, 在該類中定義對于資料庫的操作
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 省市縣關聯查詢
{
public static class SqlHelper
{
private static string connStr = ConfigurationManager.ConnectionStrings["dbConn"].ConnectionString;
public static DataTable ExecuteDataSet(string sql, params SqlParameter[] sqlParameters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.Parameters.AddRange(sqlParameters);
cmd.CommandText = sql;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
return dataSet.Tables[0];
}
}
}
public static int ExecuteNonQuery(string sql, params SqlParameter[] sqlParameters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.Parameters.AddRange(sqlParameters);
cmd.CommandText = sql;
return cmd.ExecuteNonQuery();
}
}
}
}
}
③ 建立主程式
在主程式中需要使用Area類的對象來暫時存儲查詢資訊, 定義如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 省市縣關聯查詢
{
public class Area
{
public int AreaID { get; set; }
public string AreaName { get; set; }
}
}
主視窗定義:
<Window x:Name="l" x:Class="省市縣關聯查詢.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="省市縣關聯查詢" Height="350" Width="450" Loaded="l_Loaded">
<Grid>
<StackPanel Orientation="Horizontal">
<ListBox x:Name="ProvName" DisplayMemberPath="AreaName" Width="150" SelectionChanged="ProvName_SelectionChanged"></ListBox>
<ListBox x:Name="cityName" DisplayMemberPath="AreaName" Width="150" SelectionChanged="cityName_SelectionChanged"></ListBox>
<ListBox x:Name="countryName" DisplayMemberPath="AreaName" Width="150"></ListBox>
</StackPanel>
</Grid>
</Window>
給三個ListBox控件賦予Name屬性用于背景調用, DisplayMemberPath用于綁定顯示的值.
背景代碼:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
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 省市縣關聯查詢
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void l_Loaded(object sender, RoutedEventArgs e)
{
List<Area> listProv = new List<Area>();
//AreaPid 表示該區域直屬的上級區域的 Id, Pid為0表示沒有上級直屬
DataTable table = SqlHelper.ExecuteDataSet("Select * from AreaFull where AreaPid=0");
//foreach (DataRow row in table.Rows)
//{
// Area prov = new Area();
// prov.AreaID = (int)row["AreaId"];
// prov.AreaName = (string)row["AreaName"];
// listProv.Add(prov);
//}
//定義一個方法多次使用, 代碼複用
listProv = TableToList(table);
ProvName.ItemsSource = listProv;
}
private void ProvName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
List<Area> listCity = new List<Area>();
Area prov = (Area)ProvName.SelectedItem;
int provId = prov.AreaID;
DataTable table = SqlHelper.ExecuteDataSet("Select * from AreaFull where [email protected]",
new SqlParameter("@provId", provId));
listCity = TableToList(table);
cityName.ItemsSource = listCity;
}
private void cityName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
List<Area> listCountry = new List<Area>();
Area city = (Area)cityName.SelectedItem;
//當第一級發生改動之後, 引起ProvName_SelectionChanged, 更改掉第二級的資料源
//這時會引發cityName_SelectionChanged, 并且由于目前的SelectedItem為null,
//是以如果不判斷的話, 會引起異常.
if (city != null)
{
int cityId = city.AreaID;
DataTable table = SqlHelper.ExecuteDataSet("Select * from AreaFull where [email protected]",
new SqlParameter("@cityId", cityId));
listCountry = TableToList(table);
countryName.ItemsSource = listCountry;
}
else
countryName.ItemsSource = null;
}
//将傳回的表轉換成List<Area>
private List<Area> TableToList(DataTable table)
{
List<Area> area = new List<Area>();
foreach (DataRow row in table.Rows)
{
Area city = new Area();
city.AreaID = (int)row["AreaId"];
city.AreaName = (string)row["AreaName"];
area.Add(city);
}
return area;
}
}
}
在背景中, 使用List<Area>類型的集合存儲查找傳回的資訊, 然後将控件的ItemsSource綁定到該對象上.
注意:
在進行三級關聯的時候, 需要對第三級進行SelectedItem的判斷.
當第一級發生改動之後, 引起ProvName_SelectionChanged, 更改掉第二級的資料源
這時會引發cityName_SelectionChanged, 并且由于目前的SelectedItem為null,
是以如果不判斷的話, 會引起異常
每個用于儲存存儲資訊的集合都不能在外部聲明, 除非使用ObserableList<>
效果圖:
---------------------- ASP.Net+Unity開發、 .Net教育訓練、期待與您交流! ----------------------詳細請檢視: www.itheima.com