2010-09-05 4 views
8

Ho un'applicazione WPF e sto tentando di creare uno stile TextBox utilizzando il .Net v4 Visual State Manager. Nello specifico, sto tentando di impostare i colori di Primo piano e Sfondo per lo stato di MouseOver.Impostazione dei problemi Primo piano con Visual State Manager

Quello che succede è che, mentre lo sfondo e il bordo stanno cambiando perfettamente, il primo piano non lo è. Se i pennelli che sto utilizzando ottengono il loro colore tramite una risorsa statica, il primo piano non cambia affatto. Se i pennelli che sto usando ottengono il loro colore tramite una DynamicResource, quando passo il mouse su un TextBox, cambia il primo piano di tutti i TextBox. Chiaramente, o sto facendo qualcosa di sbagliato, o quello che voglio fare semplicemente non è possibile con VSM (che sarebbe piuttosto deludente).

Qui ci sono le risorse che sto usando:

<Color x:Key="ControlBackgroundColor" R="178" G="178" B="178" A="255" /> 
<Color x:Key="ControlForegroundColor" R="0" G="0" B="0" A="255" /> 
<Color x:Key="BorderColor" R="127" G="127" B="127" A="255" /> 
<Color x:Key="MouseOverControlBackgroundColor" R="0" G="0" B="0" A="255" /> 
<Color x:Key="MouseOverControlForegroundColor" R="255" G="255" B="255" A="255" /> 
<Color x:Key="MouseOverBorderColor" R="178" G="178" B="178" A="255" /> 

<SolidColorBrush PresentationOptions:Freeze="True" x:Key="ControlBackgroundBrush" Color="{DynamicResource ControlBackgroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="ControlForegroundBrush" Color="{DynamicResource ControlForegroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="BorderBrush" Color="{DynamicResource BorderColor}" /> 

<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverControlBackgroundBrush" Color="{DynamicResource MouseOverControlBackgroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverControlForegroundBrush" Color="{DynamicResource MouseOverControlForegroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverBorderBrush" Color="{DynamicResource MouseOverBorderColor}" /> 

<Style TargetType="{x:Type TextBox}" > 
    <Setter Property="BorderThickness" Value="1"/> 
    <Setter Property="Padding" Value="2"/> 
    <Setter Property="Margin" Value="1" /> 
    <Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}" /> 
    <Setter Property="Background" Value="{DynamicResource ControlBackgroundBrush}" /> 
    <Setter Property="Foreground" Value="{DynamicResource ControlForegroundBrush}" /> 

    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="TextBox"> 
       <Grid x:Name="RootElement"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal"/> 
          <VisualState x:Name="MouseOver"> 
           <Storyboard> 
            <ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="{DynamicResource MouseOverBorderColor}" Duration="0:0:0.3"/> 
            <ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="{DynamicResource MouseOverControlBackgroundColor}" Duration="0:0:0.3"/> 
            <ColorAnimation Storyboard.TargetName="PART_ContentHost" Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)" To="{DynamicResource MouseOverControlForegroundColor}" Duration="0:0:0.3"/> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"> 
         <Grid x:Name="ContentGrid"> 
          <Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent" Background="Transparent"> 
           <ScrollViewer x:Name="PART_ContentHost" Padding="{TemplateBinding Padding}" Foreground="{TemplateBinding Foreground}" BorderThickness="0" IsTabStop="False"/> 
          </Border> 
         </Grid> 
        </Border> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

E 'molto strano per me che lo sfondo e pensionante spazzole, che vengono creati e animati esattamente nello stesso modo, funzionano perfettamente indipendentemente dal fatto che usa le risorse statiche o dinamiche, ma non il colore in primo piano.

Se qualcuno ha qualche idea, o se c'è un modo migliore per farlo, mi piacerebbe sentirlo.

David Mullin IMA Technologies

risposta

15

Le proprietà VisualStateManager non possono controllare i cui valori vengono impostati tramite un legame. Nell'esempio, sia Background sia BorderBrush sono impostati su valori locali (Transparent) e pertanto il VSM può animarli. D'altra parte, Foreground viene impostato utilizzando un TemplateBinding e così il VSM non sarà in grado di animarlo se è attivo un valore di bind.

Questa è una limitazione generale di VisualStateManager e verrà visualizzata in tutti gli esempi in cui viene utilizzata. Una strategia tipica per aggirare il problema è usare gli strati e l'opacità per dare l'illusione dell'animazione del colore quando davvero ciò che sta accadendo è una dissolvenza da un elemento all'altro. Funziona perché hai il controllo totale sul livello nascosto e non devi legarlo a nulla. Sfortunatamente questo non funzionerà per le tue necessità, anche perché l'elemento non è statico; non puoi avere due caselle di testo.

L'effetto netto è che non penso che sia possibile animare il colore di primo piano del testo e consentire al colore di primo piano di essere specificato dall'utente.