如何将数据绑定到DataGrid中的ComboBox?

时间:2011-08-15 18:39:29

标签: c# wpf linq data-binding binding

这是我正在处理的用户控件。第一个comboBox中的项目在dataGridColumn GroupID中将是相同的。

enter image description here

第一个comboBox中显示的代码是

    <ComboBox ItemsSource="{Binding}" Name="GroupComboBox" SelectedValuePath="GroupID" DisplayMemberPath="GroupName" Grid.Column="1" Margin="5" />

    private void LoadGroups()
    {
        NorthwindDataContext dc = new NorthwindDataContext();

        var groups = (from p in dc.Group
                      select p);

        this.DataContext = groups;
    }

    private void LoadStudents()
    {
        NorthwindDataContext dc = new NorthwindDataContext();

        var students = (from p in dc.Student
                         select p);

        dataGrid1.ItemsSource = students;
    }

但是在另一个comboBox中,不要出现任何项目。

            <DataGridTemplateColumn Header="GroupID">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding}" SelectedValuePath="GroupID" DisplayMemberPath="GroupName" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

我该如何绑定它?

我在考虑将所有群组放在一个列表中,但我不确定这是一个好方法,因为我需要在列表中转换我的查询。

更新1:

我不得不删除这一行:

            <DataGridComboBoxColumn Header="GroupID" ItemsSource="{Binding DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}" SelectedValuePath="GroupID" DisplayMemberPath="GroupName" />

            <DataGridTemplateColumn Header="GroupID">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}" SelectedValuePath="GroupID" DisplayMemberPath="GroupName" SelectedValue="{Binding GroupID}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

2 个答案:

答案 0 :(得分:1)

您的内部ComboBox的绑定将不起作用,因为该ComboBox的DataContext是您的Groups集合,而是Students之一,这意味着将ItemsSource设置为{{1}将{Binding}设为Student

您可以使用RelativeSource绑定向上导航到已继承的ItemsSource仍为DataContext集合的位置,例如如果通过设置Groups之间没有阻止inheritance,则此功能将起作用:

DataContext

答案 1 :(得分:0)

创建一个Group类,并在该类中包含一个公共List Students。我没有相同的名字,但我在功能上做了(我想)你在问什么。在此示例中,每个工作流程为多个批次。第二个列表框绑定到WFEnum中的选定项目。您需要使用SelectedItem.Students来获取所选组的Student集合。这是来自工作生产代码。 ElementName是告诉它绑定到控件的东西。

    <ListBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="1" Name="WFEnum" 
             ItemsSource="{Binding Path=SearchItem.SrchWorkFlows}"  
             DisplayMemberPath="Name"}">
    ...
    <ListBox Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="1" Name="WFBatchEnum"  
             ItemsSource="{Binding SelectedItem.Batches, ElementName=WFEnum}"
             DisplayMemberPath="BatchName" SelectedValuePath="ID"
             HorizontalAlignment="Left"/>

希望这有助于课堂工作流程。请注意,WorkFlow有一个公共列表批处理(为您的学生)。请注意,在这种情况下,我只是按需要从SQL获取学生,但是一旦我得到它们,我保存列表,下次不再返回SQL。 WPF和数据绑定有点复杂但很酷。

    public class Workflow : INotifyPropertyChanged
    {
        private Int16 id;
        private string name;
        private string description;       
        private Boolean active;
        private User createdBy;
        private DateTime createDate;
        private List<WFBatch> batches = new List<WFBatch>();

        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public Int16 ID { get { return id; } }
        public string Name { get { return name; } }
        public string Description { get { return description; } }           
        public Boolean Active { get { return active; } }
        public User CreatedBy { get { return createdBy; } }
        public DateTime CreateDate { get { return createDate; } }
        public WFBatch newWFbatch { get { return new WFBatch(this, App.StaticGabeLib.Search.IncludeFamilySrched); } }
        public List<WFBatch> Batches 
        {
            get
            { 
                // get the latest from SQL 
                // todo optimize - this for now will a SQL call for all batches here
                if (batches.Count > 0) return batches;
                SqlConnection sqlConnRW2 = new SqlConnection(sqlConnStringLibDef);
                try
                {
                    sqlConnRW2.Open();
                    SqlCommand sqlCmd2 = new SqlCommand();
                    sqlCmd2.Connection = sqlConnRW2;
                    SqlDataReader rdr;
                    sqlCmd2.CommandText = sqlCmd2.CommandText = "Select [ID] from [wfBch] with (nolock) " + Environment.NewLine +
                        "where [wfID] = '" + ID.ToString() + "'  order by [ID] ";
                    rdr = sqlCmd2.ExecuteReader();
                    while (rdr.Read())
                    {
                        batches.Add(new WFBatch(this, rdr.GetInt16(0)));
                    }
                }
                catch (Exception Ex)
                {
                    Debug.WriteLine(Ex.Message);
                }
                finally
                {
                    sqlConnRW2.Close();
                }  
                return batches;
            }
        }
        public Workflow(Int16 ID, string Name, string Description, Boolean Active, User CreatedBy, DateTime CreateDate)
        {
            id = ID;
            name = Name;
            description = Description;
            active = Active;
            createdBy = CreatedBy;
            createDate = CreateDate;
            // WFBatch wfBatch = new WFBatch(this);
            // todo retreive batches
        }          
    }