2009-06-28 4 views
18

Je souhaite désactiver globalement les rectangles de focus dans mon application WPF. Pour les contrôles simples qui peuvent être effectués viaDésactiver globalement FocusVisualStyle

<Style TargetType="Button"> 
    <Setter Property="FocusVisualStyle" Value="{x:Null}" /> 
</Style> 

mais comment l'appliquer à tous les contrôles de mon application. Lors de l'application à FrameworkElement rien ne se passe. Ce dont j'ai besoin serait quelque chose comme "appliquer à la classe x et à toutes les classes dérivées".

Merci à l'avance,

Stefan

Répondre

0

Cela peut ne pas être simple, mais vous pouvez écrire une fonction qui modifie le style existant d'un contrôle. Une fois cela écrit, vous pouvez écrire une fonction qui modifie récursivement le style de chaque élément.

+0

Pourquoi est-ce obtenir un -1? –

+0

Probablement parce que c'est inutilement complexe, plein de difficultés telles que s'assurer que vous avez couvert tous les cas possible et être assez difficile à maintenir, juste pour nommer 2. Comparé à un «Style» et «Setter» pour chaque type (qui, bien que fastidieux, c'est simple), votre suggestion semble fou. Je n'ai pas donné le -1. –

+0

Puisqu'il n'a pas fait de commentaire sur l'efficacité de l'une des solutions, nous ne savons pas si les autres idées ont aidé. Si c'est la seule idée qui répond à ses besoins, "fou" serait une représentation inexacte. –

0

Vous pouvez utiliser OverrideMetadata:

FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
    typeof(FrameworkElement), 
    new FrameworkPropertyMetadata(null)); 
  1. vous devez appeler cela avant tout élément est créé, l'événement est Application.Startup probablement le meilleur endroit.
  2. Cela affectera uniquement les contrôles qui utilisent le style visuel focus de FrameworkElement et ne modifieront pas les contrôles qui le remplacent dans le code ou les styles.
  3. Je n'ai pas essaye le faire avec moi-même FocusVisualStyle
+0

Malheureusement, ceci aboutit à un "PropertyMetadata est déjà enregistré pour le type 'FrameworkElement' – grayscales

+2

" Les appels à OverrideMetadata ne doivent être effectués que dans les constructeurs statiques du type qui se fournit comme paramètre forType de cette méthode, ou par instanciation similaire. : //msdn.microsoft.com/en-us/library/ms597491.aspx –

1

Je sais que cela semble fastidieux, mais vous aurez probablement à faire la même chose pour tous les autres types de contrôle, individuellement. Faire une liste d'entre eux et faire quelques opérations de recherche/remplacement simples devrait vous apporter ce dont vous avez besoin, cependant.

3

Selon http://msdn.microsoft.com/en-us/library/bb613567.aspx, vous devriez être en mesure de définir le style de mise au point global comme celui-ci:

<Style x:Key="{x:Static SystemParameters.FocusVisualStyleKey}"> 
    <Setter Property="Control.Template"> 
    <Setter.Value> 
     <ControlTemplate> 
     <Rectangle StrokeThickness="1" 
      Stroke="Black" 
      StrokeDashArray="1 2" 
      SnapsToDevicePixels="true"/> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

Je ne l'ai pas testé il, mais je suppose que lorsque vous videz le controltemplate, cela désactiverait effectivement le rectangle de focus pour l'application entière (à condition d'inclure ce style dans app.xaml).

+6

Ne fonctionne pas :( – arolson101

0

Une partie de la valeur par défaut Template pour la classe Window est un AdornerDecorator. Si vous remplacez le Window par défaut Template pour ne pas inclure un AdornerDecorator, le FocusVisualStyle sur tous les contrôles n'apparaîtra pas.

Même si un Control a une validité FocusVisualStyle qui définit un Template, il n'apparaîtra sans AdornerDecorator.

Un moyen facile d'accomplir ceci est d'inclure ce Style dans votre fichier App.xaml sous Application.Resources.

<Style TargetType="{x:Type Window}"> 
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/> 
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Window}"> 
       <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> 
        <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}"/> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
     <Trigger Property="ResizeMode" Value="CanResizeWithGrip"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Window}"> 
         <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> 
          <Grid> 
           <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}"/> 
           <ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" IsTabStop="False" Visibility="Collapsed" VerticalAlignment="Bottom"/> 
          </Grid> 
         </Border> 
         <ControlTemplate.Triggers> 
          <MultiTrigger> 
           <MultiTrigger.Conditions> 
            <Condition Property="ResizeMode" Value="CanResizeWithGrip"/> 
            <Condition Property="WindowState" Value="Normal"/> 
           </MultiTrigger.Conditions> 
           <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/> 
          </MultiTrigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Trigger> 
    </Style.Triggers> 
</Style> 
0

je suis tombé sur ce aussi bien et est venu avec cette (en effet pas très agréable mais efficace) solution:

public class FocusVisualStyleRemover 
{ 
    static FocusVisualStyleRemover() 
    { 
    EventManager.RegisterClassHandler(typeof(FrameworkElement), FrameworkElement.GotFocusEvent, new RoutedEventHandler(RemoveFocusVisualStyle), true); 
    } 

    public static void Init() 
    { 
    // intentially empty 
    } 

    private static void RemoveFocusVisualStyle(object sender, RoutedEventArgs e) 
    { 
    (sender as FrameworkElement).FocusVisualStyle = null; 
    } 
} 

Dans mon constructeur de MainWindow je puis juste appeler FocusVisualStyleRemover.Init();

Questions connexes