1

何度かこの問題に遭遇しました。

たとえば、メニューを右クリックするか、セル内のコンボボックスを選択して、SelectedItemまたは選択した列を検索する場合。SelectedItemはnullまたは以前に選択された行になります。

private void ComboBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
// Correct  
m_BeginEditString = ((ComboBox)sender).SelectedValue.ToString(); 

// Wrong. selected item is last selected row, example clicking directly on combobox will not select row, and be null.
m_BeginEditRow = (RowItem)MyDataGrid.SelectedItem; 
}   

<DataGridTemplateColumn>
   <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <ComboBox SelectedItem="{Binding myItem, Mode=TwoWay, 
NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
ItemsSource="{Binding Source={StaticResource enum}}" 
SelectionChanged="ComboBox_Changed" 
LostKeyboardFocus="ComboBox_LostKeyboardFocus" 
GotKeyboardFocus="ComboBox_GotKeyboardFocus" />
        </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
 </DataGridTemplateColumn>
4

2 に答える 2

1

@Ramesh Muthiah の方向性に感謝します。

private void ComboBox_Changed(object sender, SelectionChangedEventArgs e) {
if (((ComboBox)sender).IsLoaded) { // disregard SelectionChangedEvent fired on population from binding
    if (e.RemovedItems.Count != 0) {
        for (Visual visual = (Visual)sender; visual != null; visual = (Visual)VisualTreeHelper.GetParent(visual)) { // Traverse tree to find corred selected item
            if (visual is DataGridRow) {
                DataGridRow row = (DataGridRow)visual;
                m_BeginEditRow = new MyRowItem((MyRowItem)row.Item); // Copy constructor, otherwise passed by reference
                break;
            }
        }
        MyEnum newItem = (MyEnum)e.AddedItems[0];
        MyEnum oldItem = (MyEnum)e.RemovedItems[0];
        if (m_BeginEditRow.Combo1 == newItem) {
            m_BeginEditRow.Combo1 = oldItem;
        } else {
            m_BeginEditRow.Combo2 = oldItem;
        }
        DoStuff(m_BeginEditRow, false);
    }
}

}

于 2013-01-29T18:53:30.967 に答える
1

選択したアイテムに直接アクセスする代わりに、親オブジェクトを介してアクセスし、必要なものにアクセスしようとすることができます。これは代替アプローチです。これがお役に立てば幸いです

Combobox objMyButton = null;
        if (sender is Combobox)
        {
            objMyButton = (sender as Combobox );    
        }

        //You can access the parent object which means corresponding DataGridRow and do whatever you want

        for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
            if (vis is DataGridRow)
            {
                var row = (DataGridRow)vis;                 
                break;
            }
于 2013-01-29T15:29:21.207 に答える