如何给WPF中的DataGrid的ComBox编辑列添加数据

violet_han 2011-12-27 05:22:08
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>
...全文
878 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
DENQH 2011-12-29
  • 打赏
  • 举报
回复
当combox和gridview同时绑定同一个表的主键就可以实现你的要求
Icedmilk 2011-12-29
  • 打赏
  • 举报
回复
现在访问数据库都要创建与数据相关的实体类

Employer就是这样的一个类

DataSet这种东西太落后了

看看Entity Framework吧
violet_han 2011-12-29
  • 打赏
  • 举报
回复
能不能说的具体点,DataSet部分是整个项目添加数据源后控件在绑定相关数据源时自动生成的。
我现在添加的DataGrid控件是为了批量输入数据的,其中两列(姓名和机种名)是下拉框列,供用户选择的,可以省去输入的繁琐和错误的产生,现在能显示选项了,但是DataGrid为什么不显示已经编辑的列值呢?
[Quote=引用 8 楼 icedmilk 的回复:]
现在访问数据库都要创建与数据相关的实体类

Employer就是这样的一个类

DataSet这种东西太落后了

看看Entity Framework吧
[/Quote]
Icedmilk 2011-12-28
  • 打赏
  • 举报
回复
这是个蛮复杂的事情

首先你需要给你的Combox绑定待选的数据

<DataGrid x:Name="gridEmployers" AutoGenerateColumns="False" ItemsSource="{Binding}" DataContext="{Binding}"> <DataGridTemplateColumn.CellEditingTemplate>
<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 } };
}
Icedmilk 2011-12-28
  • 打赏
  • 举报
回复
这是个蛮复杂的事情

首先你需要给你的Combox绑定待选的数据

<DataGrid x:Name="gridEmployers" AutoGenerateColumns="False" ItemsSource="{Binding}" DataContext="{Binding}"> <DataGridTemplateColumn.CellEditingTemplate>
<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 } };
}
木水云 2011-12-28
  • 打赏
  • 举报
回复
可以将dataGridView和数据库中的表绑定。
例如:Datatable data=new Datatable();
this.dataGridView1.DataSource=data;
violet_han 2011-12-28
  • 打赏
  • 举报
回复
怎么木有人回答啊

现在要解决的是怎么给ComboBox绑定数据
在Xaml中,绑定了数据库中的整个表后,为什么运行时没有显示选项,下拉框是空白的呢
<ComboBox Name="xmComb" DisplayMemberPath="xm" SelectedValuePath="gh" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Source=Table_xz}" />
若要在.cs文件中写代码的话,怎么将查询的结果集合绑定到xmComb上呢
violet_han 2011-12-28
  • 打赏
  • 举报
回复
目前,这个DataGrid中的下拉框能显示选项了(显示的是数据库中表的字段,而不是查询后的数据集合,退而求其次了),但是DataGrid的行在编辑时不显示已经编辑的内容,不知道什么原因,大家帮忙看一下吧,代码如下:
//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();
}
violet_han 2011-12-28
  • 打赏
  • 举报
回复
能不能就我的问题回答啊 我要绑定的数据来自SQL数据库中的表,不是自己写的类
violet_han 2011-12-28
  • 打赏
  • 举报
回复
能不能就我的问题回答啊 我要绑定的数据是从数据库中查询得到的,不是自己写的

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧