2008-10-01 7 views
3

Dans une application sur laquelle je travaille, nous avons un ensemble de contrôles personnalisés avec leurs ControlTemplates définis dans Generic.xaml.Définition du focus sur un contrôle dans un ControlTemplate dans WPF

Par exemple, notre zone de texte personnalisé ressemblerait à ceci:

<Style TargetType="{x:Type controls:FieldTextBox}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type controls:FieldTextBox}"> 
       <Border BorderThickness="0" Margin="5"> 
        <StackPanel ToolTip="{Binding Path=Field.HintText, RelativeSource={RelativeSource TemplatedParent}}"> 
         <TextBlock Text="{Binding Path=Field.FieldLabel, RelativeSource={RelativeSource TemplatedParent}}" 
            HorizontalAlignment="Left" 
            /> 
         <TextBox Width="{Binding Path=Field.DisplayWidth, RelativeSource={RelativeSource TemplatedParent}}" 
           HorizontalAlignment="Left" 
           Text="{Binding Path=Field.Data.CurrentValue, RelativeSource={RelativeSource TemplatedParent}}" 
           IsEnabled="{Binding Path=Field.IsEnabled, RelativeSource={RelativeSource TemplatedParent}}" 
           ContextMenu="{Binding Source={StaticResource FieldContextMenu}}" > 
          <TextBox.Background> 
           <SolidColorBrush Color="{Binding Path=Field.CurrentBackgroundColor, RelativeSource={RelativeSource TemplatedParent}}"/> 
          </TextBox.Background> 
         </TextBox> 
        </StackPanel> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="Focusable" Value="True" /> 
    <Setter Property="IsTabStop" Value="False" /> 
</Style> 

Dans notre application, nous devons être en mesure de mettre l'accent sur programatically un contrôle particulier dans le ControlTemplate.

Dans notre code C#, nous pouvons obtenir le "FieldTextBox" particulier basé sur nos données. Une fois que nous avons le FieldTextBox correct, nous devons être en mesure de mettre l'accent sur la TextBox réelle contenue dans le ControlTemplate.

La meilleure solution que j'ai trouvé est de définir un nom sur le contrôle principal dans chaque modèle de contrôle (dans ce cas, c'est le TextBox), comme "FocusableControl".

Mon code (contenu dans le code-behind pour le FieldTextBox) pour se concentrer ensuite mis sur le contrôle serait:

Control control = (Control)this.Template.FindName("FocusableControl", this); 
    if (control != null) 
    { 
     control.Focus(); 
    } 

Cette solution fonctionne. Cependant, quelqu'un d'autre sait-il d'une solution qui serait plus efficace que cela?

Répondre

2

Dans votre modèle de contrôle, vous pouvez ajouter un déclencheur qui définit le paramètre FocusedElement du FocusManager du StackPanel dans la zone de texte que vous souhaitez cibler. Vous définissez la propriété du déclencheur sur {TemplateBinding IsFocused} afin qu'il se déclenche lorsque le contrôle conteneur est mis au point.

+0

Il suffit de définir la propriété du déclencheur sur "IsFocused". La solution fonctionne, mais je ne suis pas sûr que ce soit vraiment plus efficace. –

+1

Nous pourrions obtenir une réponse acceptée ici si vous pouviez élaborer sur votre solution. J'essaie de faire quelque chose de similaire et j'expérimente avec vos suggestions, mais je ne suis pas complètement à la suite de ce que la liaison Value du déclencheur ressemblerait entre autres détails. – jpierson

0

Vous pouvez vous débarrasser du codage en dur du nom de contrôle dans le code en fournissant un certain DependancyProperty et avoir le même code dans la fonction controlLoaded ou OnApplyTemplate basée sur le DependancyProperty. L'expéditeur de cet DependancyProperty sera le candidat pour l'appel .Focus(). TemplateBinding n'est pas nécessaire pour le trigger ControlTemplate.

+0

Je ne suis pas sûr si je comprends entièrement votre solution. Pourriez-vous être plus clair ou donner un petit exemple? –

Questions connexes