2010-04-14 15 views
7

estoy tratando de conseguir un DataGridTemplateColumn a comportarse de forma idéntica a un TextColumn¿Cómo seleccionar todo el texto cuando el cuadro de texto de edición en un DataGridTemplateColumn recibe foco?

  • cuando la célula entra en el modo de edición (Pulse F2), el usuario puede inmediatamente empezar a escribir el nuevo valor
  • por defecto, se selecciona el contenido de texto existente - para que pueda establecer nuevos valores fácilmente

Se ha hecho el primero; sin embargo, seleccionar todo el texto no funciona. Como se menciona en una serie de publicaciones, intenté conectarme al evento GotFocus y seleccionar todo el texto en código subyacente. Esto funcionó para un cuadro de texto independiente; sin embargo, para un Textbox que es el control de edición para una TemplateColumn, esto no funciona.

¿Alguna idea? Código de ejemplo:

<Window.Resources> 
      <Style x:Key="HighlightTextBoxStyle" TargetType="{x:Type TextBox}"> 
       <EventSetter Event="GotFocus" Handler="SelectAllText"/> 
       <EventSetter Event="GotMouseCapture" Handler="SelectAllText"/> 
       <Setter Property="Background" Value="AliceBlue"/> 
      </Style> 

      <DataTemplate x:Key="DefaultTitleTemplate"> 
       <TextBlock Text="{Binding Title}"/> 
      </DataTemplate> 
      <DataTemplate x:Key="EditTitleTemplate"> 
        <TextBox x:Name="Fox" 
         FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}" 
         Text="{Binding Path=Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
         Style="{StaticResource HighlightTextBoxStyle}"> 
        </TextBox> 
      </DataTemplate> 
     </Window.Resources> 
     <DockPanel> 
      <TextBox DockPanel.Dock="Top" x:Name="Test" Text="{Binding Path=(FocusManager.FocusedElement).Name, ElementName=MyWindow}" 
        Style="{StaticResource HighlightTextBoxStyle}"/> 
      <toolkit:DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"> 
       <toolkit:DataGrid.Columns> 
        <toolkit:DataGridTemplateColumn Header="Templated Title" 
         CellTemplate="{StaticResource DefaultTitleTemplate}" 
         CellEditingTemplate="{StaticResource EditTitleTemplate}" /> 

        <toolkit:DataGridTextColumn Header="Title" Binding="{Binding Path=Title}" /> 
       </toolkit:DataGrid.Columns> 
      </toolkit:DataGrid> 
     </DockPanel> 
+0

Por lo que puedo decir, este problema aún no se ha resuelto. – Dabblernl

+0

@Dabblernl - prueba si funciona el siguiente parche de cinta de conducto. – Gishu

Respuesta

6

omitida actualizar el post con una respuesta ...

El problema parece ser que para una columna de cuadrícula de datos personalizados (también conocido como un DataGridTemplateColumn) que la red no tiene manera de conocer la tipo exacto del control de edición (que se especifica a través de un DataTemplate y podría ser cualquier cosa). Para DataGridTextColumn, el tipo de control de edición es conocido y, por lo tanto, la cuadrícula puede encontrarlo e invocar un SelectAll() en él.

Para alcanzar el objetivo final de una TemplateColumn, debe proporcionar una ayuda. Olvidé cómo lo resolví la primera vez ... pero he aquí algo que busqué hoy. Cree una derivación personalizada de una TemplateColumn con una anulación del método PrepareCellForEdit como se muestra a continuación (Cambie el cuadro de texto con su control de edición exacto).

public class MyCustomDataColumn : DataGridTemplateColumn 
    { 
     protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs) 
     { 
      var contentPresenter = editingElement as ContentPresenter; 

      var editingControl = FindVisualChild<TextBox>(contentPresenter); 
      if (editingControl == null) 
       return null; 

      editingControl.SelectAll(); 
      return null; 
     } 

     private static childItem FindVisualChild<childItem>(DependencyObject obj) 
    } 

Aquí es an implementation for FindVisualChild.

XAML:

<WPFTestBed:MyCustomDataColumn Header="CustomColumn" 
        CellTemplate="{StaticResource DefaultTitleTemplate}" 
        CellEditingTemplate="{StaticResource EditTitleTemplate}"/> 
</DataGrid.Columns> 

gran cantidad de código para una inconsistencia molesto.

+0

Lo siento, era demasiado tarde para otorgarle la bonificación. ¡Muchas gracias! – Dabblernl

+0

@Dabblernl - Dejé de perseguir a un representante después de conocer a Mr.Skeet n friends :) Estoy feliz de ayudar. – Gishu

+0

En mi caso, también tuve que enfocarme en la edición de TextBox 'editingControl.Focus();' 'editingControl.SelectAll();' –

0

Sé que esto es muy tarde, pero tomé un enfoque diferente y creativamente extendí la clase TextBox. Realmente no me gusta usar el booleano para verificar si el texto ya está definido, pero el problema es que los eventos de selección se disparan antes de que el texto se establezca desde el enlace, por lo que SelectAll() no tiene nada que seleccionar. Esta clase probablemente solo sea útil como plantilla de edición en algo así como DataGridTemplateColumn. Cada solución que encontré para este problema es bastante pirata, así que no me siento tan mal con esta ... :)

class AutoSelectTextBox : TextBox 
{ 
    private bool _autoSelectAll= true; 

    protected override void OnInitialized(EventArgs e) 
    { 
     // This will cause the cursor to enter the text box ready to 
     // type even when there is no content. 
     Focus(); 
     base.OnInitialized(e); 
    } 

    protected override OnKeyDown(System.Windows.Input.KeyEventArgs e) 
    { 
     // This is here to handle the case of an empty text box. If 
     // omitted then the first character would be auto selected when 
     // the user starts typing. 
     _autoSelectAll = false; 
     base.OnKeyDown(e); 
    } 


    protected override void OnTextChanged(TextChangedEventArgs e) 
    { 
     if (_autoSelectAll) 
     { 
      SelectAll(); 
      Focus(); 
      _autoSelectAll= false; 
     } 
     base.OnTextChanged(e); 
    } 
} 
Cuestiones relacionadas