2010-04-14 3 views
7

Je suis en train d'obtenir un DataGridTemplateColumn à se comporter de manière identique à un TextColumnComment sélectionner tout le texte lorsque la zone de texte d'édition dans un DataGridTemplateColumn reçoit le focus?

  • lorsque la cellule passe en mode d'édition (Appuyez sur F2), l'utilisateur peut immédiatement commencer à taper la nouvelle valeur
  • par défaut, le contenu de texte existant est sélectionné - de sorte que vous pouvez définir de nouvelles valeurs facilement

Vous avez terminé le premier; Cependant, la sélection de tout le texte ne fonctionne pas. Comme mentionné par un certain nombre de messages, essayé d'accrocher dans l'événement GotFocus et en sélectionnant tout le texte dans le code-behind. Cela a fonctionné pour une zone de texte autonome; Toutefois, pour une zone de texte qui est le contrôle d'édition pour un TemplateColumn, cela ne fonctionne pas.

Des idées? Exemple de code:

<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

Pour autant que je peux dire cette question est encore en suspens. – Dabblernl

+0

@Dabblernl - essayez si le correctif de bande-conduit suivant fonctionne. – Gishu

Répondre

6

Missed mise à jour du poste avec une réponse ...

Le problème semble être que pour une colonne de grille de données personnalisées (alias un DataGridTemplateColumn) la grille n'a aucun moyen de connaître la type exact du contrôle d'édition (qui est spécifié via un DataTemplate et pourrait être n'importe quoi). Pour un DataGridTextColumn, le type de contrôle d'édition est connu et donc la grille peut le trouver et invoquer un SelectAll() dans celui-ci. Pour atteindre l'objectif final d'une TemplateColumn, vous devez fournir une assistance. J'ai oublié comment je l'ai résolu la première fois ... mais voici quelque chose que j'ai cherché - modifié aujourd'hui. Créez une dérivation personnalisée d'un TemplateColumn avec un remplacement de la méthode PrepareCellForEdit comme indiqué ci-dessous (Swap Textbox avec votre contrôle d'édition exact).

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) 
    } 

est ici an implementation for FindVisualChild.

XAML:

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

Lot de code pour une incohérence ennuyeux.

+0

Désolé, il était trop tard pour vous offrir le bonus. Merci beaucoup! – Dabblernl

+0

@Dabblernl - arrêté de poursuivre rep après avoir rencontré M.Skeet n amis :) Juste heureux d'aider. – Gishu

+0

Dans mon cas, j'ai également dû mettre l'accent sur l'édition TextBox 'editingControl.Focus();' 'editingControl.SelectAll();' –

0

Je sais que c'est très tard, mais j'ai adopté une approche différente et étendu de manière créative la classe TextBox. Je n'aime pas vraiment utiliser le booléen pour vérifier si le texte est déjà défini mais le problème est que les événements de sélection se déclenchent avant que le texte ne soit défini à partir de la liaison, ainsi SelectAll() n'a rien à sélectionner! Cette classe est probablement utile uniquement en tant que modèle d'édition dans quelque chose comme un DataGridTemplateColumn. Chaque solution que je trouve pour ce problème est à peu près un hack donc je ne me sens pas trop mal dans celui-ci ... :)

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); 
    } 
} 
Questions connexes