在DataGrid的單元格中嵌入ComboBox是十分常見且是經(jīng)常使用的一個操作。在上一篇中,我為大家介紹了如何使用靜態(tài)資源綁定作為ComboBox的數(shù)據(jù)源。然而,在實際開發(fā)的過程中,我們經(jīng)常會碰到處理動態(tài)數(shù)據(jù)的問題。本文將為大家介紹如何動態(tài)綁定DataGrid中ComboBox的數(shù)據(jù)源。
準(zhǔn)備工作
1)測試項目的建立
請參考我的Silverlight-a-powerful-DataGrid-component-2-data-exchange-of-the-ADO.NET-Entity-Framework">強大的DataGrid組件[2]_數(shù)據(jù)交互之ADO.NET Entity Framework——Silverlight學(xué)習(xí)筆記[10]。
2)創(chuàng)建測試用數(shù)據(jù)庫
為了實現(xiàn)數(shù)據(jù)聯(lián)動,我們需要在測試數(shù)據(jù)庫Employees中創(chuàng)建如下的兩張數(shù)據(jù)表。(使用SQL Server">SQL Server Express創(chuàng)建)
兩表的字段屬性:
[Employee]
[Department]
關(guān)系圖:
創(chuàng)建Linq to SQL數(shù)據(jù)模型
具體步驟參照我的強大的DataGrid組件[3]_數(shù)據(jù)交互之Linq to SQL——Silverlight學(xué)習(xí)筆記[11]。
下面是EmployeeModel.dbml圖
建立Silverlight-enabled WCF Web Service
具體步驟參照我的強大的DataGrid組件[3]_數(shù)據(jù)交互之Linq to SQL——Silverlight學(xué)習(xí)筆記[11]。
我們需要建立如下的兩個Silverlight-enabled WCF Web Service。
EmployeesInfoSevice.svc.cs代碼如下:
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
using EmployeesContext;//引入數(shù)據(jù)庫實體所在命名空間
using EmployeesEntities;//引入數(shù)據(jù)表實體所在命名空間
namespace DataGridnComboBox
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class EmployeesInfoSevice
{
[OperationContract]
public List<Departments> GetEmployeesDepartment()
{
EmployeeModelDataContext db = new EmployeeModelDataContext();
return db.Departments.ToList();
}
// Add more operations here and mark them with [OperationContract]
}
}
EmployeesInfo2Sevice.svc.cs代碼如下:
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
using EmployeesContext;//引入數(shù)據(jù)庫實體所在命名空間
using EmployeesEntities;//引入數(shù)據(jù)表實體所在命名空間
namespace DataGridnComboBox
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class EmployeesInfo2Service
{
[OperationContract]
public List<Employees> GetEmployeesInfo(int departmentid)
{
EmployeeModelDataContext db = new EmployeeModelDataContext();
return db.Employees.Where(x => x.DepartmentID == departmentid).ToList();
}
// Add more operations here and mark them with [OperationContract]
}
}
建立完成按Ctrl+Shift+B進行編譯。
創(chuàng)建SilverlightClient界面及組件代碼
MainPage.xaml代碼:
<UserControl
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"
mc:Ignorable="d" xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="SilverlightClient.MainPage"
d:DesignWidth="320" d:DesignHeight="240">
<Grid x:Name="LayoutRoot" Width="320" Height="240" Background="White">
<dataInput:Label Height="20" HorizontalAlignment="Left" Margin="8,12,0,0" VerticalAlignment="Top" Width="43" FontSize="16" Content="部門:"/>
<ComboBox x:Name="cbDepartment" Height="32" HorizontalAlignment="Left" Margin="59,6,0,0" VerticalAlignment="Top" Width="137" FontSize="14"/>
<data:DataGrid x:Name="dgFilter" AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="8,60,0,57" Width="267" FontSize="14">
<data:DataGrid.Columns>
<data:DataGridTemplateColumn Header="查詢姓名" Width="100">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding EmployeeName}"></TextBlock>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
<data:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="CB" Loaded="CB_Loaded" Width="100" SelectedItem="{Binding EmployeeName,Mode=TwoWay}" /><!--注意:這里是實施動態(tài)聯(lián)動的關(guān)鍵-->
</DataTemplate>
</data:DataGridTemplateColumn.CellEditingTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
</Grid>
</UserControl>
MainPage.xaml.cs代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Data.Services.Client;
using SilverlightClient.EmployeesInfoWCFService;
using SilverlightClient.EmployeesInfo2WCFService;
namespace SilverlightClient
{
public partial class MainPage : UserControl
{
List<Employees> cbCBListProvider = new List<Employees>();
List<string> cbCBContent = new List<string>();
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
this.cbDepartment.SelectionChanged += new SelectionChangedEventHandler(cbDepartment_SelectionChanged);
}
void cbDepartment_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (cbDepartment.SelectedItem != null)
{
int departmentid = ((Departments)cbDepartment.SelectedItem).DepartmentID;
EmployeesInfo2ServiceClient webClient = new EmployeesInfo2ServiceClient();
webClient.GetEmployeesInfoAsync(departmentid);
webClient.GetEmployeesInfoCompleted +=
new EventHandler<GetEmployeesInfoCompletedEventArgs>(webClient_GetEmployeesInfoCompleted);
}
}
void webClient_GetEmployeesInfoCompleted(object sender, GetEmployeesInfoCompletedEventArgs e)
{
cbCBListProvider = e.Result.ToList<Employees>();
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
//示例數(shù)據(jù)
List<Employees> em = new List<Employees>();
em.Add(new Employees() { EmployeeName = "張三" });
em.Add(new Employees() { EmployeeName = "李四" });
dgFilter.ItemsSource = em;
EmployeesInfoSeviceClient webClient = new EmployeesInfoSeviceClient();
webClient.GetEmployeesDepartmentAsync();
webClient.GetEmployeesDepartmentCompleted +=
new EventHandler<GetEmployeesDepartmentCompletedEventArgs>(webClient_GetEmployeesDepartmentCompleted);
}
void webClient_GetEmployeesDepartmentCompleted(object sender, GetEmployeesDepartmentCompletedEventArgs e)
{
cbDepartment.ItemsSource = e.Result;
cbDepartment.DisplayMemberPath = "DepartmentName";
}
void CB_Loaded(object sender, RoutedEventArgs e)//處理dgFilter加載的ComboBox的數(shù)據(jù)源
{
ComboBox curComboBox = sender as ComboBox;
cbCBContent.Clear();
cbCBListProvider.ForEach(x => cbCBContent.Add(x.EmployeeName));
curComboBox.ItemsSource = cbCBContent;
}
}
}
最終效果圖