2009-06-28 36 views
18

Desidero disattivare globalmente i rettangoli di messa a fuoco nella mia applicazione WPF. Per i singoli controlli che possono essere eseguiti tramiteDisattiva FocusVisualStyle a livello globale

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

ma come applicarlo a tutti i controlli nella mia applicazione. Quando si applica a FrameworkElement non accade nulla. Quello di cui ho bisogno sarebbe qualcosa come "applica alla classe x e tutte le classi derivate".

Grazie in anticipo,

Stefan

risposta

0

questo potrebbe non essere semplice, ma si potrebbe scrivere una funzione che altera lo stile esistente di un controllo. Una volta che è scritto, puoi scrivere una funzione che altera in modo ricorsivo lo stile di ogni elemento.

+0

Perché ha fatto questo prendi un -1? –

+0

Probabilmente perché è inutilmente complesso, pieno di difficoltà come assicurare di aver coperto ogni caso limite ed essere piuttosto difficile da mantenere, solo per nominare 2. Rispetto a uno 'Stile' e 'Setter' per ogni tipo (che, sebbene noioso, è semplice), il tuo suggerimento suona folle. Non ho dato il -1. –

+0

Dal momento che non ha fatto un commento sul fatto che nessuna delle soluzioni funzionerà, non sappiamo se le altre idee hanno aiutato. Se questa è l'unica idea che soddisfa i suoi bisogni, "folle" sarebbe una rappresentazione imprecisa. –

0

È possibile utilizzare OverrideMetadata:

FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
    typeof(FrameworkElement), 
    new FrameworkPropertyMetadata(null)); 
  1. si deve chiamare questo prima della creazione di qualsiasi elemento, l'evento Application.Startup è probabilmente il posto migliore.
  2. Ciò avrà effetto solo sui controlli che utilizzano lo stile di visualizzazione dello stato attivo di FrameworkElement e non cambierà i controlli che lo sovrascrivono nel codice o negli stili.
  3. non ho tentativi fare questo con me stesso FocusVisualStyle
+0

Sfortunatamente questo risulta in un "PropertyMetadata è già registrato per il tipo" FrameworkElement " – grayscales

+2

" Le chiamate a OverrideMetadata devono essere eseguite solo all'interno dei costruttori statici del tipo che si fornisce come parametro forType di questo metodo o attraverso un'istanza simile. "Http : //msdn.microsoft.com/en-us/library/ms597491.aspx –

1

So che può sembrare noioso, ma probabilmente hanno a che fare la stessa cosa per tutti gli altri tipi di controllo, singolarmente. Fare una lista di questi e fare un paio di semplici operazioni Trova/Sostituisci dovrebbe farti ottenere ciò di cui hai bisogno, comunque.

3

Secondo http://msdn.microsoft.com/en-us/library/bb613567.aspx, si dovrebbe essere in grado di impostare lo stile approccio globale come questo:

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

non ho ancora testato ma suppongo che quando svuoti il ​​controltemplate, questo disabiliti efficacemente il rettangolo di attivazione per l'intera app (ammesso che tu includa questo stile in app.xaml).

+6

Non funziona :( – arolson101

0

Parte del valore predefinito Template per la classe Window è un AdornerDecorator. Se si sostituisce il valore Template predefinito per non includere AdornerDecorator, lo FocusVisualStyle su tutti i controlli non verrà visualizzato.

Anche se un Control ha una valida FocusVisualStyle che imposta un Template, non verrà visualizzato senza il AdornerDecorator.

Un modo semplice per eseguire ciò è includere questo Style nel file App.xaml sotto 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

mi sono imbattuto su questo come bene e si avvicinò con questo (anzi non molto bello ma efficace) Soluzione:

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

nel costruttore di mio MainWindow ho poi basta chiamare FocusVisualStyleRemover.Init();

Problemi correlati