此方法很笨拙,並不推薦使用!!!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",要否則,點選了了幾個,就選中了幾個