DataGrid中ComboBox联动问题

adhitler 2013-09-27 01:29:19
有一个Datagrid,里面有ComboBox和另外一些列,大概是这样:

<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name}" Header="姓名" IsReadOnly="True" Width="80" />
<DataGridTemplateColumn Header="护照号">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="PassportNumber" ItemsSource="{Binding Path=Passports}" DisplayMemberPath="PasprotNumber" SelectedIndex="0" SelectionChanged="PassportNumber_SelectionChanged" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="护照有效期" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>

Datagrid的数据源是一个 人员的列表 可以叫 List<Person>
Person的属性有姓名和护照(Name和List<Passport>)
护照(Passport)有护照号和有效期。
这个表格大概意思是列出所有人员,然后每个人有多本护照,每本护照有效期不同

护照号那一列是下拉框,从下拉框选择不同护照后,希望可以联动后面的护照有效期
后台C#代码:
private void PassportNumber_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox combobox = sender as ComboBox;//这里可以获取到ComboBox
//但是后面怎样获取到同一行的签证有效期呢,以便给他更新为所选护照的有效期
}


数据绑定没有问题,问题就是上面后台代码注释里写的,怎样更新有效期呢?
非常非常感谢
...全文
334 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
tang3567 2013-10-08
  • 打赏
  • 举报
回复
说说如果是我,我的做法 第一个Combobox属性Tag="{Binding }" 第二个ComboBox属性SelectedValue="{Binding 有效期}" 第一个Combobox做一个选择项发生变化时的事件 对象 实例 = ComboBox.Tag as 对象; 实例.有效期 = 3; 第二个ComboBox的SelectedValue就会变成3
Bonjour-你好 2013-09-29
  • 打赏
  • 举报
回复
引用 6 楼 adhitler 的回复:
        private void PassportNumber_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox cb = sender as ComboBox;
            String cbStr = ((Passport)cb.SelectedItem).PasprotNumber;

            //ComBobox所在的行(最终)
            DataGridRow row = null;
            for (Int32 i = 0; i < this.dataGrid1.Items.Count; i++) {
                row = (DataGridRow)this.dataGrid1.ItemContainerGenerator.ContainerFromIndex(i);
                //当前行第二列的单元格数据
                ComboBox temp = null;
                ContentPresenter cp = this.dataGrid1.Columns[1].GetCellContent(row) as ContentPresenter;
                if (cp != null) {
                    temp = cp.ContentTemplate.FindName("PassportNumber", cp) as ComboBox;
                }

                //判断当前行是否是改变行
                if (temp.SelectedIndex > -1 && ((Passport)temp.SelectedItem).PasprotNumber == cbStr) {
                    break;
                } else {
                    row = null;
                }
            }

            if (row != null) {
                //ComBobox所在的行的第三列的单元格数据
                TextBlock tb = this.dataGrid1.Columns[2].GetCellContent(row) as TextBlock;
                if (tb != null) {
                    try {
                        Passport passport = (Passport)cb.SelectedItem;
                        tb.Text = passport.IssueDate.ToShortDateString() + " 至 " + passport.ExpiryDate.ToShortDateString();
                    } catch (Exception ex) {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
        }
adhitler 2013-09-29
  • 打赏
  • 举报
回复
引用 5 楼 KumaPower 的回复:
        private void PassportNumber_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //默认DataGrid只能单选,且选中行为是一行
            if (this.dataGrid1.SelectedItems.Count == 1) {
                Person person = this.dataGrid1.SelectedItem as Person;
                if (person != null) {
                    //获取当前选中项的索引号
                    Int32 num = this.dataGrid1.SelectedIndex;
                    //获取当前行
                    DataGridRow row = this.dataGrid1.ItemContainerGenerator.ContainerFromIndex(num) as DataGridRow;
                    if (row != null) {
                        //所选行第二列的单元格数据
                        ComboBox cb = null;
                        ContentPresenter cp = this.dataGrid1.Columns[1].GetCellContent(row) as ContentPresenter;
                        if (cp != null) {
                            cb = cp.ContentTemplate.FindName("PassportNumber",cp) as ComboBox;
                        }

                        //所选行第三列的单元格数据
                        TextBlock tb = this.dataGrid1.Columns[2].GetCellContent(row) as TextBlock;

                        if (cb != null && tb != null) {
                            String cbStr = cb.Text;
                            try {
                                var temp = person.Passports.Where(x => x.PasprotNumber == cbStr).Single();
                                tb.Text = temp.IssueDate.ToShortDateString() + " 至 " + temp.ExpiryDate.ToShortDateString();
                            } catch (Exception ex) {
                                MessageBox.Show(ex.Message);
                            }
                        }
                    }
                }
            }
        }
原本打算用数据绑定的,但不会搞。。。写得有点丑 PS:那个护照号码应该是唯一的吧(你上面给的数据护照号码是一样),如果不唯一,那代码还需要改。
首先非常感谢这位大哥的热心帮忙,我看你的代码受到很大启发,目前我实际的代码是这样了:
private void PassportNumber_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
	ComboBox combobox = sender as ComboBox;//触发Change事件的ComboBox
	if (e.AddedItems == null || e.AddedItems.Count == 0)
	{
		return;
	}
	Passport passport = e.AddedItems[0] as Passport;//下来框改变值后,新值对应的Passport

	//获取当前选中项的索引号
	Int32 num = dataPersonInfo.SelectedIndex;

	if (num == -1)
		return;

	//获取当前行
	DataGridRow row = dataPersonInfo.ItemContainerGenerator.ContainerFromIndex(num) as DataGridRow;
	if (row != null)
	{
		//护照有效期那一列是第9列
		TextBlock cp = dataPersonInfo.Columns[8].GetCellContent(row) as TextBlock;
		if (cp != null)
		{
			cp.Text = passport.ExpiryDate.ToString("yyyy-MM-dd");
		}
	}
}
但这里有个问题,就是对于任何联动,都是基于选中行
//获取当前选中项的索引号
Int32 num = dataPersonInfo.SelectedIndex;
但是,其实常常改变下拉框时,那时那一列并不是选中的,比如窗口刚加载时,或者通过代码改变ComboBox的选中等,这时就不能用这句获取当前选中项的索引号,来获取该ComboBox的所在行了。 实际上,我现在可以通过
ComboBox combobox = sender as ComboBox;//触发Change事件的ComboBox
来获取到发生Change事件的ComboBox,那么我觉着,应该可以根据这个ComboBox找到他的所在行,这样就完美了,请问有什么方法吗?
Bonjour-你好 2013-09-27
  • 打赏
  • 举报
回复
        private void PassportNumber_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //默认DataGrid只能单选,且选中行为是一行
            if (this.dataGrid1.SelectedItems.Count == 1) {
                Person person = this.dataGrid1.SelectedItem as Person;
                if (person != null) {
                    //获取当前选中项的索引号
                    Int32 num = this.dataGrid1.SelectedIndex;
                    //获取当前行
                    DataGridRow row = this.dataGrid1.ItemContainerGenerator.ContainerFromIndex(num) as DataGridRow;
                    if (row != null) {
                        //所选行第二列的单元格数据
                        ComboBox cb = null;
                        ContentPresenter cp = this.dataGrid1.Columns[1].GetCellContent(row) as ContentPresenter;
                        if (cp != null) {
                            cb = cp.ContentTemplate.FindName("PassportNumber",cp) as ComboBox;
                        }

                        //所选行第三列的单元格数据
                        TextBlock tb = this.dataGrid1.Columns[2].GetCellContent(row) as TextBlock;

                        if (cb != null && tb != null) {
                            String cbStr = cb.Text;
                            try {
                                var temp = person.Passports.Where(x => x.PasprotNumber == cbStr).Single();
                                tb.Text = temp.IssueDate.ToShortDateString() + " 至 " + temp.ExpiryDate.ToShortDateString();
                            } catch (Exception ex) {
                                MessageBox.Show(ex.Message);
                            }
                        }
                    }
                }
            }
        }
原本打算用数据绑定的,但不会搞。。。写得有点丑 PS:那个护照号码应该是唯一的吧(你上面给的数据护照号码是一样),如果不唯一,那代码还需要改。
adhitler 2013-09-27
  • 打赏
  • 举报
回复
上面代码有地方忘改了,就是 PersonInfoMore 和PersonInfo 都当成PersonInfo就行了
adhitler 2013-09-27
  • 打赏
  • 举报
回复
引用 2 楼 KumaPower 的回复:
能否给个张三或李四的数据源?不想自己写数据测试
我写上 两个人员和护照测试数据吧,实体类就那几个字段,就先不贴了。 获取人员列表方法:
/// <summary>
/// 临时测试数据
/// </summary>
/// <returns></returns>
private static List<PersonInfoMore> CreateAMoreTestList()
{
	List<PersonInfoMore> Personlist = new List<PersonInfoMore>();
	PersonInfoMore PI = new PersonInfoMore();
	PI.Id = 1;
	PI.NameCh = "李娜";
	PI.Passports=new  PassportService().GetPassportListByPerson(PI);
	Personlist.Add(PI);

	PersonInfoMore PI1 = new PersonInfoMore();
	PI1.Id = 2;
	PI1.NameCh = "刘明";
	PI1.Passports=new  PassportService().GetPassportListByPerson(PI1);
	Personlist.Add(PI1);

	return Personlist;
}
护照信息:
/// <summary>
/// 护照管理服务
/// </summary>
public class PassportService
{
	/// <summary>
	/// 获取某人所有护照
	/// </summary>
	/// <param name="person">The person.</param>
	/// <param name="includeInvalid">是否包含无效的</param>
	/// <returns></returns>
	public List<Passport> GetPassportListByPerson(PersonInfo person, bool includeInvalid = false)
	{
		List<Passport> passportList = new List<Passport>();
		Passport p1 = new Passport();
		p1.PasprotNumber = "P83293";
		p1.IssueDate = new DateTime(2012, 3, 21);
		p1.ExpiryDate = new DateTime(2017, 3, 21);
		p1.ChineseName = "马三立";
		p1.EnglishName = "Three Horse Stand";

		Passport p2 = new Passport();
		p2.PasprotNumber = "P83293";
		p2.IssueDate = new DateTime(2010, 5, 9);
		p2.ExpiryDate = new DateTime(2011, 5, 9);
		p1.ChineseName = "温+宝";
		p1.EnglishName = "Warm Home Baby";

		passportList.Add(p1);
		passportList.Add(p2);
		return passportList;
	}

}
Bonjour-你好 2013-09-27
  • 打赏
  • 举报
回复
能否给个张三或李四的数据源?不想自己写数据测试
adhitler 2013-09-27
  • 打赏
  • 举报
回复

8,734

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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