此方法很笨拙,并不推荐使用!!!ide
此方法很笨拙,并不推荐使用!!!测试
此方法很笨拙,并不推荐使用!!!this
事件原由,同事用了公司一个继承ComboBox的的自定义可编辑控件,可是发现这个控件在DataGrid中,当点击第一次的时候,光标到了ComboBox中,可是ComboBox所在的DataGrid行却不被选中,仍是在原来的选中行上,这个问题,就致使了一些列问题,引发的问题,咱们不作讨论。spa
通过测试,发现并非自定义控件自己的问题,而是ComboBox只要设置了IsEditable="True",而且放在DataGrid中,就会存在这个问题,缘由是,焦点在ComboBox内部的Textbox上,而没有在ComboBox自身上,看了下MSDN上的源码,若是设置了IsEditable="True",在Textbox拿到焦点之后,handled就会设置为True。code
尝试重写了一下ComboBox的一些事件,可是并不起做用,百度、谷歌都走过了,也没有发现有相似相关的问题,断断续续花了两天时间,没有好的办法,最后,只能笨拙的解决这个问题了。blog
先看下效果图:继承
“好使的”列就是笨拙方法解决的,“很差使的”列就是正常的ComboBox设置了IsEditable="True"熟悉。经过效果图不难看出我刚才说的问题。 事件
<DataGrid x:Name="dgTest" ItemsSource="{Binding MoList}" CanUserAddRows="False" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTemplateColumn Header="好使的" Width="*"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox x:Name="cb" IsEditable="True"ItemsSource="{Binding DataContext.DmList,RelativeSource={RelativeSource AncestorType=DataGrid}}" SelectedValue="{Binding Dm2}" SelectedValuePath="Dm" DisplayMemberPath="Dm" Text="{Binding Dm2}" GotFocus="ComboBox_GotFocus"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="很差使的" Width="*"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox IsEditable="True" ItemsSource="{Binding DataContext.DmList,RelativeSource={RelativeSource AncestorType=DataGrid}}" SelectedValue="{Binding Dm2}" SelectedValuePath="Dm" DisplayMemberPath="Dm" Text="{Binding Dm2}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
private void ComboBox_GotFocus(object sender, RoutedEventArgs e) {for (int i = 0; i < dgTest.Items.Count; i++) { DataGridTemplateColumn templateColumn = dgTest.Columns[0] as DataGridTemplateColumn; FrameworkElement element = templateColumn.GetCellContent(dgTest.Items[i]); if (element!=null) { ComboBox combo = templateColumn.CellTemplate.FindName("cb", element) as ComboBox; if ((ComboBox)sender == combo) { dgTest.SelectedIndex = i; } } } }
经过上面的代码,我相信广大的程序猿们能看出,为何这个方法笨拙了,由于须要给DataGrid设置Name,给ComboBox设置Name、GotFocus,还要写死ComboBox所在的列标。因此,这个方法虽然解决了问题,可是,真心的不推荐你们使用,若是谁有好的方法,但愿能够留言,谢谢了。element
同事看到我这段代码之后,有点疑惑,不直接用IsFocused之后,进行判断。源码
咱们将代码修改成如下的,并在if的位置打上断点,发现,不管点击哪一个ComboBox,IsFocused始终是False,这是由于,TextboxFocus之后,直接拦截了,因此,没有办法继续触发。
但愿,有好的解决办法的大神,给个留言,在此十分感谢了,若是,有的朋友,也遇到了这个问题,没有其余好的解决办法的话,不如尝试下,我这个笨拙的方法,最起码是解决问题了。
推荐此方法!!!
推荐此方法!!!
推荐此方法!!!
这个方法是小丁同窗提供的思路,就是在ComboBox的GotFocus事件里查找父,也就是所在的行。
public static T GetParentObject<T>(DependencyObject obj, string name) where T : FrameworkElement { DependencyObject parent = VisualTreeHelper.GetParent(obj); while (parent != null) { if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name))) { return (T)parent; } parent = VisualTreeHelper.GetParent(parent); } return null; }
protected override void OnGotFocus(RoutedEventArgs e) { base.OnGotFocus(e); DataGridRow row = FindHelper.GetParentObject<DataGridRow>(this, ""); row.IsSelected = true; }
写一个控件,继承自ComboBox,而后重写GotFocus,这个好处是能够随意使用,不会定死了。
可是,须要设置DataGrid的SelectionMode="Single",要否则,点选了了几个,就选中了几个