WPF项目中现有一个DataGrid,其中有一个名为“姓名”的模板列和名为“工号”的文本列,模板列在编辑时是一个ComBox,要实现的功能:ComBox的选项是从数据查询得到的姓名列表(如人员表中性别为女的人的姓名列表),选择其中的某个姓名,TextBlock显示选择的该姓名,“工号”列显示该姓名的工号,如何实现数据的绑定及将记录保存到数据库中
<DataGrid AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" Margin="12,200,0,130" Name="dataGrid1" ItemsSource="{Binding}" Width="613">
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="selectxmCol" Header="姓名" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Name="selectXm" Text="{Binding Path=xm}" ></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Grid Name="selectxmGrid" FocusManager.FocusedElement="{Binding ElementName=xmComb}">
<ComboBox Name="xmComb" DisplayMemberPath="xm" SelectedValuePath="gh" IsEditable="True" IsSynchronizedWithCurrentItem="True"></ComboBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="工号" Binding="{Binding Path=gh}" Width="100"/>
</DataGrid.Columns>
</DataGrid>
<DataGrid AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" Margin="12,200,0,130" Name="dataGrid1" ItemsSource="{Binding}" Width="613">
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="selectxmCol" Header="姓名" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Name="selectXm" Text="{Binding Path=xm}" ></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Grid Name="selectxmGrid" FocusManager.FocusedElement="{Binding ElementName=xmComb}">
<ComboBox Name="xmComb" DisplayMemberPath="xm" SelectedValuePath="gh" IsEditable="True" IsSynchronizedWithCurrentItem="True"></ComboBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="工号" Binding="{Binding Path=gh}" Width="100"/>
</DataGrid.Columns>
</DataGrid>
在Xaml中,绑定了数据库中的整个表后,为什么运行时没有显示选项,下拉框是空白的呢
<ComboBox Name="xmComb" DisplayMemberPath="xm" SelectedValuePath="gh" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Source=Table_xz}" />
若要在.cs文件中写代码的话,怎么将查询的结果集合绑定到xmComb上呢
例如:Datatable data=new Datatable();
this.dataGridView1.DataSource=data;
<DataTemplate>
<ComboBox Text="{Binding Name}"
IsEditable="True"
DisplayMemberPath="Name"
ItemsSource="{Binding Source={StaticResource employers}}"
SelectionChanged="OnChangeNameSelection"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<Window.Resources>
<ObjectDataProvider x:Key="employers" ObjectType="{x:Type local:_2011_12_28_01_Data}" MethodName="GetEmployers"/>
</Window.Resources>是用ObjectDataProvider来获取数据
public class _2011_12_28_01_Data
{
public IEnumerable<Employer> GetEmployers()
{
return new Employer[]{
new Employer{ Name="A", Id=1},
new Employer{ Name="B", Id=2},
new Employer{ Name="C", Id=3},
new Employer{ Name="D", Id=4},
new Employer{ Name="E", Id=5}
};
}
}然后需要给Combox添加SelectionChanged事件: private void OnChangeNameSelection(object sender, SelectionChangedEventArgs e)
{
var data = this.FindResource("employers") as ObjectDataProvider;
var employers = data.Data as IEnumerable<Employer>; var cmb = sender as ComboBox;
var selectedItem = this.gridEmployers.SelectedItem as Employer;
var employer = employers.FirstOrDefault(x => x.Name == (cmb.SelectedItem as Employer).Name);
if (employer != null) {
selectedItem.Id = employer.Id;
selectedItem.Name = employer.Name;
}
}最后一点就是给你的数据实现INotifyPropertyChanged接口,否则看不到效果 public class Employer : INotifyPropertyChanged
{
public string Name
{
get { return name; }
set
{
name = value;
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public string name;
public int Id
{
get { return id; }
set
{
id = value;
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("Id"));
}
}
}
public int id; public event PropertyChangedEventHandler PropertyChanged;
}
注意,DataGrid和Combox绑定的不一样
给DataGrid绑定是在初始化随便加一个作为示例
public _2011_12_28_01()
{
InitializeComponent();
this.DataContext = new Employer[] { new Employer { Name = "A", Id = 1 } };
}
<DataTemplate>
<ComboBox Text="{Binding Name}"
IsEditable="True"
DisplayMemberPath="Name"
ItemsSource="{Binding Source={StaticResource employers}}"
SelectionChanged="OnChangeNameSelection"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<Window.Resources>
<ObjectDataProvider x:Key="employers" ObjectType="{x:Type local:_2011_12_28_01_Data}" MethodName="GetEmployers"/>
</Window.Resources>是用ObjectDataProvider来获取数据
public class _2011_12_28_01_Data
{
public IEnumerable<Employer> GetEmployers()
{
return new Employer[]{
new Employer{ Name="A", Id=1},
new Employer{ Name="B", Id=2},
new Employer{ Name="C", Id=3},
new Employer{ Name="D", Id=4},
new Employer{ Name="E", Id=5}
};
}
}然后需要给Combox添加SelectionChanged事件: private void OnChangeNameSelection(object sender, SelectionChangedEventArgs e)
{
var data = this.FindResource("employers") as ObjectDataProvider;
var employers = data.Data as IEnumerable<Employer>; var cmb = sender as ComboBox;
var selectedItem = this.gridEmployers.SelectedItem as Employer;
var employer = employers.FirstOrDefault(x => x.Name == (cmb.SelectedItem as Employer).Name);
if (employer != null) {
selectedItem.Id = employer.Id;
selectedItem.Name = employer.Name;
}
}最后一点就是给你的数据实现INotifyPropertyChanged接口,否则看不到效果 public class Employer : INotifyPropertyChanged
{
public string Name
{
get { return name; }
set
{
name = value;
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public string name;
public int Id
{
get { return id; }
set
{
id = value;
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("Id"));
}
}
}
public int id; public event PropertyChangedEventHandler PropertyChanged;
}
注意,DataGrid和Combox绑定的不一样
给DataGrid绑定是在初始化随便加一个作为示例
public _2011_12_28_01()
{
InitializeComponent();
this.DataContext = new Employer[] { new Employer { Name = "A", Id = 1 } };
}
//Xaml相应代码:
<UserControl.Resources>
<my:ygclDataSet x:Key="ygclDataSet" />
<CollectionViewSource x:Key="table_xzViewSource" Source="{Binding Path=Table_xz, Source={StaticResource ygclDataSet}}" />
<CollectionViewSource x:Key="table_jzViewSource" Source="{Binding Path=Table_jz, Source={StaticResource ygclDataSet}}" />
<CollectionViewSource x:Key="table_czyViewSource" Source="{Binding Path=Table_czy, Source={StaticResource ygclDataSet}}" />
</UserControl.Resources> <DataGrid AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" Margin="12,200,0,130" Name="dataGrid1" Width="613" IsReadOnly="False" IsSynchronizedWithCurrentItem="True">
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="selectxmCol" Header="姓名" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Name="selectedXm" Text="{Binding ElementName=xmComb,Path=Text}" ></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Grid Name="selectxmGrid" FocusManager.FocusedElement="{Binding ElementName=xmComb}">
<ComboBox Name="xmComb" DisplayMemberPath="xm" SelectedValuePath="gh" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource table_czyViewSource}}"></ComboBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="工号" Binding="{Binding ElementName=xmComb,Path=SelectedValue}" Width="100"/>
<DataGridComboBoxColumn Header="机种名" DisplayMemberPath="jzm" SelectedValuePath="jzm" ItemsSource="{Binding Source={StaticResource table_jzViewSource}}" Width="100"/>
<DataGridTextColumn Header="生产工时" Width="100"/>
<DataGridTextColumn Header="实际产量" Width="100"/>
</DataGrid.Columns>
</DataGrid>
//.cs文件相应代码:
//setData()用来显示没有数据的DataGrid,因为这个DataGrid是用来输入数据的
void setData()
{
DataTable dt = new DataTable();
dt.Columns.Add("xm");
dt.Columns.Add("gh");
dt.Columns.Add("jzm");
dt.Columns.Add("shcgs");
dt.Columns.Add("sjcl");
dataGrid1.ItemsSource = dt.DefaultView;
}private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
setData();
WpfApplication1.ygclDataSet ygclDataSet = ((WpfApplication1.ygclDataSet)(this.FindResource("ygclDataSet")));
// 将数据加载到表 Table_jz 中。
WpfApplication1.ygclDataSetTableAdapters.Table_jzTableAdapter ygclDataSetTable_jzTableAdapter = new WpfApplication1.ygclDataSetTableAdapters.Table_jzTableAdapter();
ygclDataSetTable_jzTableAdapter.Fill(ygclDataSet.Table_jz);
System.Windows.Data.CollectionViewSource table_jzViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("table_jzViewSource")));
table_jzViewSource.View.MoveCurrentToFirst();
// 将数据加载到表 Table_czy 中。
WpfApplication1.ygclDataSetTableAdapters.Table_czyTableAdapter ygclDataSetTable_czyTableAdapter = new WpfApplication1.ygclDataSetTableAdapters.Table_czyTableAdapter();
ygclDataSetTable_czyTableAdapter.Fill(ygclDataSet.Table_czy);
System.Windows.Data.CollectionViewSource table_czyViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("table_czyViewSource")));
table_czyViewSource.View.MoveCurrentToFirst();
}
我现在添加的DataGrid控件是为了批量输入数据的,其中两列(姓名和机种名)是下拉框列,供用户选择的,可以省去输入的繁琐和错误的产生,现在能显示选项了,但是DataGrid为什么不显示已经编辑的列值呢?