2015-01-27 34 views
8

Ich habe ein Datagrid in WPF mit einem DataGridTextColum und einem DataGridTemplateColum.Automatische Bearbeitung von WPF Datagrid Inhalt, wenn Datagrid-Zelle den Fokus erhält

<DataGridTextColumn Width="4*" IsReadOnly="True" x:Name="dataGridColumnDescription" 
Header="Description" Binding="{Binding Description}"> 
</DataGridTextColumn> 

<DataGridTemplateColumn CellStyle="{StaticResource CellEditing}" IsReadOnly="False" Width="*" Header="Value" 
CellEditingTemplateSelector="{StaticResource myCellEditingTemplateSelectorValue}" 
CellTemplateSelector="{StaticResource myCellTemplateSelectorValue}"> 
</DataGridTemplateColumn> 

Die CellTemplateSelectors geben einen Datatemplate mit einem Textblock für die die Celltemplate resp. eine TextBox für CellEditing!

<DataTemplate x:Key="dGridStringValueTemplate"> 
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Path=Value}"/> 
</DataTemplate> 

<DataTemplate x:Key="dGridStringValueTemplateEditing"> 
    <TextBox TextAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" BorderThickness="1" Text="{Binding Path=Value, UpdateSourceTrigger=LostFocus}"/> 
</DataTemplate> 

Jetzt möchte ich automatisch die TextBox Fokus, wenn die Datagridcell den Fokus erhält. Der Benutzer sollte in der Lage sein, den TextBox-Inhalt zu bearbeiten, ohne die Zelle doppelt anzuklicken.

ich diesen Artikel gefunden:

DataGrid Tips & Tricks: Single-Click Editing , wo ich die aktuelle Datagridcell bekommen, aber wie kann ich den Inhalt zugreifen, um die Textbox den Fokus zu geben, um den Inhalt zu bearbeiten?

Das ist mein Stil:

<Style x:Key="CellEditing" TargetType="{x:Type DataGridCell}"> 
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="myDataGridMain_PreviewMouseLeftButtonDown"></EventSetter> 
</Style> 

Das ist mein Event-Handler:

private void myDataGridMain_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    DataGridCell cell = sender as DataGridCell;  // cell ist not null 

    DataGridTemplateColumn col = cell.Column as DataGridTemplateColumn; //col is not null 

    DataTemplate template = col.CellTemplate; //this is null 
} 

Wie kann ich die Textbox mit dem Event-Handler bekommen?

+0

Wenn Sie Ihr Gitter sein wollen jederzeit bearbeitbar Warum willst du eine Vorlage bearbeiten? fügen Sie einfach Zellschablone mit Textfeld darin hinzu und ändern Sie Art des Textkastens selbst auf diese Weise Sie müssen nicht Fokusmaterial schreiben – WPFKK

Antwort

2

ich es geschafft, nicht die beste Lösung, aber es funktioniert ... wenn die Zelle den Fokus erhält ich es in den Bearbeitungsmodus eingestellt.

private void myDataGridMain_OnFocus(object sender, RoutedEventArgs e) 
{ 
    DataGridCell cell = sender as DataGridCell; 
    if (cell != null) 
     cell.IsEditing = true; 
    //var test = FindVisualChild<TextBlock>(cell); 
} 

Auf Keydown suche ich nach dem visuellen Kind und gebe den Fokus.

private void myDataGridMain_KeyDown(object sender, KeyEventArgs e) 
     { 
      DataGridCell cell = sender as DataGridCell; 

      if (e.Key == Key.Enter) 
      { //give cell the focus 
       cell.Focus(); 
      } 
      else 
      { 
       if ((cell != null)) 
       { 
        TextBox textbox = FindVisualChild<TextBox>(cell); 
        if (textbox != null) 
        { //TextBox has benn found 
         if ((textbox as TextBox).IsFocused == false) 
         { 
          (textbox as TextBox).SelectAll(); 
         } 
         (textbox as TextBox).Focus(); 
        } 

        CheckBox chkbox = FindVisualChild<CheckBox>(cell); 
        if (chkbox != null) 
        { //Checkbox has been found 
         (chkbox as CheckBox).Focus(); 
        } 

        ComboBox combbox = FindVisualChild<ComboBox>(cell); 
        if (combbox != null) 
        { //ComboBox has been found 
         (combbox as ComboBox).Focus(); 
        } 
       } 
      } 
     } 

Finden Sie Visual Child!

public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject 
{ 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
     if (child != null && child is T) 
      return (T)child; 
     else 
     { 
      T childOfChild = FindVisualChild<T>(child); 
      if (childOfChild != null) 
       return childOfChild; 
     } 
    } 
    return null; 
} 
11

Dies scheint zu funktionieren:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn> 
       <DataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <TextBox FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"></TextBox> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellEditingTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
+0

Danke für Ihre Antwort.In Kombination mit einem Template-Selektor funktioniert das nicht :( – nullxff

+1

Danke, du bist ein toller Zauberer! – Yola

0

Dieser Ansatz funktioniert für mich. Es nutzt die Tatsache, dass die DataGrid wird immer eine neue Instanz der Vorlage erstellen, wenn die Bearbeitung beginnt:

<DataGridTemplateColumn.CellEditingTemplate> 
    <DataTemplate> 
     <TextBox Text="{Binding MyProperty}" 
       Loaded="TextBox_Loaded"></TextBox> 
    </DataTemplate> 
</DataGridTemplateColumn.CellEditingTemplate> 

und in der Code-behind:

private void TextBox_Loaded(object sender, RoutedEventArgs e) 
{ 
    ((TextBox)sender).Focus(); 
    ((TextBox)sender).SelectAll(); 
} 

Als zusätzlichen Bonus, es wählt auch alle Text in der Zelle. Es sollte funktionieren, egal, wie Sie den Bearbeitungsmodus (Doppelklick, Klick, F2 drücken)

0

die einfache Antwort für die neue Steuerung von Datagrid-Steuerelement abgeleitet schaffen

using System.Windows.Controls; 

    public class CustomDataGrid : DataGrid 
    { 

    protected override void OnSelectedCellsChanged(SelectedCellsChangedEventArgs e) 
    { 
     //to make sure cell is selected 
     var cells = e.AddedCells.FirstOrDefault(); 
     if (cells != null) 
     { 
      this.BeginEdit(); 

     } 
     base.OnSelectedCellsChanged(e); 
    } 

    } 
Verwandte Themen