2015-03-18 3 views
0

Я создаю столбцы datagrid динамически на основе проанализированного файла csv. По сути, я следую методу here, однако я использую DataGridTemplateColumn, поскольку мне нужно указать комбо как элемент управления редактирования.wpf datagrid single click edit с DataGridTemplateColumn не работает

Я также хочу иметь один клик редактирования, и я следую за технику, предложенную в этой статье here by Julie Lerman, который обвила комбо в сетке и использовали FocusManager.FocusedElement для установки фокуса.

Я делаю это в ViewModel и код, чтобы создать комбинированный элемент выглядит следующим образом:

private static FrameworkElementFactory CreateComboElement(int columnIndex, List<string> fieldNameMappings) 
{ 
    //note we create the combo in a grid and use the FocusManager to get focus on 1 click! 

    //so first the grid 
    FrameworkElementFactory gridElement = new FrameworkElementFactory(typeof(Grid)); 
    Binding gridBinding = new Binding(); 
    gridBinding.ElementName = "combo"; 
    gridElement.SetValue(System.Windows.Input.FocusManager.FocusedElementProperty, gridBinding); 

    //now the combo 
    FrameworkElementFactory cboElement = new FrameworkElementFactory(typeof(ComboBox)); 
    gridElement.AppendChild(cboElement); 

    //set the ItemsSource on the combo 
    Binding comboBinding = new Binding(); 
    comboBinding.Source = fieldNameMappings; 
    cboElement.SetBinding(ComboBox.ItemsSourceProperty, comboBinding); 
    cboElement.SetValue(ComboBox.NameProperty, "combo"); 
    cboElement.SetValue(ComboBox.IsSynchronizedWithCurrentItemProperty, false); 

    //now set the binding for the selected vlaue in the combo 
    Binding selectedBinding = new Binding(string.Format("Properties[{0}].Value", columnIndex)); 
    cboElement.SetBinding(ComboBox.SelectedItemProperty, selectedBinding); 
    return gridElement; 
} 

Проблема заключается в том, один клик редактирования не работает и во время выполнения я вижу следующее ошибка после 2 клика, которая все еще требуется для вызова редактирования:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=combo'. BindingExpression:(no path); DataItem=null; target element is 'Grid' (Name=''); target property is 'FocusedElement' (type 'IInputElement') 

Что случилось, почему это один щелчок не работает?

ответ

0

Вы должны перехватить событие OnGotFocus в DataGridCell, установите режим ячейки в IsEditing, затем перехватывает нагруженное событие для управления актером в вашем CellEditingTemplate:

<Window.Resources> 
    <Style 
     x:Key="AutoEditModeOnClick" 
     TargetType="{x:Type DataGridCell}"> 

     <EventSetter Event="GotFocus" Handler="DataGridCell_OnGotFocus" /> 
    </Style> 
</Window.Resources> 

<DataGrid.Columns> 
    <DataGridTemplateColumn 
     CellStyle="{StaticResource AutoEditModeOnClick}" 
     Header="Score"> 

     <!-- Example with ComboBox --> 

     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <!-- Some more XAML --> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 

     <DataGridTemplateColumn.CellEditingTemplate> 
      <DataTemplate> 
       <!-- Some more XAML --> 
       <ComboBox 
        DisplayMemberPath="Description" 
        SelectedValuePath="RecordID" 
        SelectedValue="{Binding Score, 
         TargetNullValue=0, 
         UpdateSourceTrigger=PropertyChanged}" 
        ItemsSource="{Binding DataContext.ScoreOptions, 
         RelativeSource={RelativeSource 
          AncestorType={x:Type DataGrid}}}" 
        Loaded="Combobox_Loaded"/> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellEditingTemplate> 
    </DataGridTemplateColumn> 

    <DataGridTemplateColumn 
     CellStyle="{StaticResource AutoEditModeOnClick}" 
     Header="Comment"> 

     <!-- Example with TextBox --> 

     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <!-- Some more XAML --> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 

     <DataGridTemplateColumn.CellEditingTemplate> 
      <DataTemplate> 
       <!-- Some more XAML --> 
       <TextBox 
        Loaded="TextBox_Loaded" 
        Text="{Binding Comment, 
         UpdateSourceTrigger=LostFocus}"/> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellEditingTemplate> 
    </DataGridTemplateColumn> 
</DataGrid.Columns> 

В коде-позади, вам нужно три обработчика; один для ячейки и один для каждого типа управления (ComboBox, TextBox):

/// <summary> 
    /// Skips the 'DataGridCell.Focus' step and goes straight into IsEditing 
    /// </summary> 
    private void DataGridCell_OnGotFocus(object sender, RoutedEventArgs e) 
    { 
     DataGridCell cell = sender as DataGridCell; 
     cell.IsEditing = true; 
    } 

    /// <summary> 
    /// Skips the 'IsEditing' step and goes straight into IsDropDownOpen 
    /// </summary> 
    private void Combobox_Loaded(object sender, RoutedEventArgs e) 
    { 
     ComboBox comboBox = sender as ComboBox; 
     comboBox.IsDropDownOpen = true; 
    } 

    /// <summary> 
    /// Skips the 'IsEditing' step and goes straight into Focus 
    /// </summary> 
    private void TextBox_Loaded(object sender, RoutedEventArgs e) 
    { 
     TextBox textBox = sender as TextBox; 
     textBox.Focus(); 
    }