2009-11-23 9 views
4

Je crée un UserControl personnalisé à utiliser dans un modèle d'édition DataGrid. Il ressemble à ceci:WPF Popup focus dans la grille de données

<UserControl 
    x:Class="HR.Controls.UserPicker" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Grid> 
     <TextBlock x:Name="PART_TextBox" Text="Hello WOrld" /> 
     <Popup Width="234" Height="175" IsOpen="True" StaysOpen="True" 

      Placement="Bottom" 
      PlacementTarget="{Binding ElementName=PART_TextBox}" 
     > 
      <TextBox 
        x:Name="searchTextBox" 
        Text="&gt;Enter Name&lt;"/> 
     </Popup> 
    </Grid> 
</UserControl> 

modifier: J'ai PRECISEE un peu le code. Il semble que si je mets directement un popup avec la zone de texte dans le CellEditingTemplate, la zone de texte ne se focalise pas. Lorsque je déplace ce code dans un UserControl, je ne peux plus sélectionner la zone de texte lors de la modification de la cellule.

Le UserControl fait-il quelque chose de drôle avec le focus?


Le problème est quand je modifier la cellule dans la grille de données que je reçois le contrôle de l'utilisateur montrant mais je ne peux pas cliquer dans la zone de texte searchTextBox. Lorsque je clique dessus, la fenêtre se ferme et la cellule revient à la valeur par défaut.

J'ai essayé de copier et coller tout le code dans le contrôle utilisateur et de le coller directement dans le CellEditingTemplate et cela interagit comme il le devrait.

Je me demandais juste si le contrôle UserControl a fait quelque chose de bizarre qui empêche un popup de gagner le focus parce qu'il fonctionne comme prévu lorsqu'il est directement placé dans le CellEditingTemplate?

Merci, Raul

+1

Eh bien, le UserControl a quelque chose de bizarre avec ce qui ne traite pas la mise au point d'un Popup pour faire partie de son auto. J'ai donc dû créer un Custom Control et scratcher le UserControl. Ce fut une douleur mais vaut la peine pour la liberté que vous obtenez. – HaxElit

Répondre

2

moi avons eu un problème un peu Simular, j'ai créé un usercontrol contenant une zone de texte, un bouton et un calendrier. Basicaly je crée mon propre datepicker avec la logique de validation personnalisée.

Je mets ce composant dans un CellEditingTemplate. Lorsque j'ai appuyé sur le bouton, la fenêtre contextuelle a montré, mais en cliquant sur la fenêtre contextuelle, la cellule a été arrêtée (parce que la fenêtre contextuelle prenait le focus dans la zone de texte). Je l'ai résolu en ajoutant du code qui signifiait que si le popup était ouvert, le focus de la zone de texte ne serait pas perdu. Cela a fait l'affaire pour moi.

De plus, dans le gestionnaire d'événements on on de la commande usercontrol je mets l'accent sur la zone de texte. Dans votre cas, il s'agit probablement de la commande Usercontrol itsefl.

protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e) { 
      // Don't allow focus to leave the textbox if the popup is open 
      if (Popup.IsOpen) e.Handled = true; 
} 

private void Root_Loaded(object sender, RoutedEventArgs e) { 
     TextBox.Focus(); 
} 
3

J'ai eu un problème similaire où un Popup incorporé dans un UserControl comme modèle d'édition de la cellule fermerait lorsque certaines zones de celui-ci ont été cliqués. Le problème s'est avéré être que le WPF Toolkit (et vraisemblablement WPF4) DataGrid est très gourmand avec des clics de souris gauche. Même lorsque vous les manipulez et définissez Handled sur true, la grille peut les interpréter comme cliquant dans une cellule différente.

Ce thread a tous les détails, mais le correctif est de connecter événement DataGrid.CellEditEnding et annuler la modification de fin:

private static void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
    if (e.Column.GetType() == typeof(DataGridTemplateColumn)) 
    { 
     var popup = GetVisualChild<Popup>(e.EditingElement); 
     if (popup != null && popup.IsOpen) 
     { 
      e.Cancel = true; 
     } 
    } 
} 

private static T GetVisualChild<T>(DependencyObject visual) 
    where T : DependencyObject 
{ 
    if (visual == null) 
     return null; 

    var count = VisualTreeHelper.GetChildrenCount(visual); 
    for (int i = 0; i < count; i++) 
    { 
     var child = VisualTreeHelper.GetChild(visual, i); 

     var childOfTypeT = child as T ?? GetVisualChild<T>(child); 
     if (childOfTypeT != null) 
      return childOfTypeT; 
    } 

    return null; 
} 

Crédit complet pour cela va à l'Actipro thread.

+0

Fonctionne comme un charme !! – JanW

3

Je ne sais pas si cela va aider quelqu'un, mais cela aide si vous avez des contrôles personnalisés dans la grille de données avec un popup ..... cela a résolu mon problème, et c'était une ligne de xaml. Je passe toute la journée à relire ce forum puis à regarder la source de DataGridCell. J'espère que cela t'aides.

<Style TargetType="{x:Type DataGridCell}"> 
     <Setter Property="Focusable" Value="False"></Setter> 
    </Style> 
+1

C'est la solution de travail la plus simple possible pour avoir une popup dans un DataGridCell. – Abbas

Questions connexes