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>

解决方案 »

  1.   

    怎么木有人回答啊现在要解决的是怎么给ComboBox绑定数据
    在Xaml中,绑定了数据库中的整个表后,为什么运行时没有显示选项,下拉框是空白的呢
    <ComboBox Name="xmComb" DisplayMemberPath="xm" SelectedValuePath="gh"  VerticalAlignment="Top" Width="120" ItemsSource="{Binding Source=Table_xz}" />
    若要在.cs文件中写代码的话,怎么将查询的结果集合绑定到xmComb上呢
      

  2.   

    可以将dataGridView和数据库中的表绑定。
    例如:Datatable data=new Datatable();
    this.dataGridView1.DataSource=data;
      

  3.   

    这是个蛮复杂的事情首先你需要给你的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 } };
            }
      

  4.   

    这是个蛮复杂的事情首先你需要给你的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 } };
            }
      

  5.   

    能不能就我的问题回答啊  我要绑定的数据来自SQL数据库中的表,不是自己写的类
      

  6.   

    目前,这个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();
    }
      

  7.   

    现在访问数据库都要创建与数据相关的实体类Employer就是这样的一个类DataSet这种东西太落后了看看Entity Framework吧
      

  8.   

    能不能说的具体点,DataSet部分是整个项目添加数据源后控件在绑定相关数据源时自动生成的。
    我现在添加的DataGrid控件是为了批量输入数据的,其中两列(姓名和机种名)是下拉框列,供用户选择的,可以省去输入的繁琐和错误的产生,现在能显示选项了,但是DataGrid为什么不显示已经编辑的列值呢?
      

  9.   

    当combox和gridview同时绑定同一个表的主键就可以实现你的要求