2010-09-03 7 views
13

Ho cercato di creare una casella di testo con un suggerimento che viene visualizzato quando è vuoto. Sto riscontrando problemi nell'impostazione del testo del suggerimento all'interno di uno stile.WPF Associazione alla proprietà padre dall'elemento nidificato utilizzando lo stile

Per essere precisi, questo funziona (vale a dire, si lega correttamente):

<TextBox Tag="hint text"> 
     <TextBox.Background> 
      <VisualBrush Stretch="None"> 
       <VisualBrush.Visual> 
        <TextBlock Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=TextBox}}" FontStyle="Italic" Foreground="LightGray" /> 
       </VisualBrush.Visual> 
      </VisualBrush> 
     </TextBox.Background> 
    </TextBox> 

ma, quando mi sposto allo stile, non è così:

<Style TargetType="TextBox" x:Key="stlHintbox"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Mode=Self}}" Value=""> 
      <Setter Property="Background"> 
       <Setter.Value> 
        <VisualBrush Stretch="None"> 
         <VisualBrush.Visual> 
          <TextBlock Tag="inner" Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=TextBox}}" 
             FontStyle="Italic" Foreground="LightGray" /> 
         </VisualBrush.Visual> 
        </VisualBrush> 
       </Setter.Value> 
      </Setter> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

<TextBox Tag="hint text" Style="{StaticResource stlHintbox}" /> 

Allora, qual è il trucco? Come posso legare la proprietà degli antenati all'interno di uno stile?

risposta

12

Il problema non è con il RelativeSource, ma con il modo in cui si utilizza il VisualBrush. Ricorda che gli stili sono condivisi tra gli elementi a cui li si applica. La ragione per cui il tuo esempio non funziona è che, in effetti, stai provando a condividere una singola casella di testo (quella che hai taggato "inner") con più caselle di testo principali.

Per capire perché questo è un problema, provare un esperimento mentale: la casella di testo interna viene creata una volta (in linea di massima, ciò avverrà quando lo stile viene creato). A quale delle caselle di testo a cui viene applicato lo stile deve essere scelto come antenato della casella di testo interna quando si utilizza l'associazione RelativeSource?

Ecco perché DataTemplates e ControlTemplates esistono in WPF. Invece di istanziare direttamente le immagini, definiscono un modello che consente di creare più copie di elementi visivi secondo necessità.

+0

Ok, questo ha davvero senso ... Ho passato i libri troppo velocemente sembra :) – veljkoz

5

Reativeource non funziona come previsto. È preferibile creare una casella di testo filigrana utilizzando il modello di controllo. Ma la versione potrebbe funzionare:

<Window.Resources> 
    <Style TargetType="TextBox" x:Key="stlHintbox"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Mode=Self}}" Value=""> 
       <Setter Property="TextBox.Background"> 
        <Setter.Value> 
         <VisualBrush Stretch="None" Visual="{Binding ElementName=hintText}"/> 
        </Setter.Value> 
       </Setter> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<StackPanel> 
    <TextBox Tag="hint text" x:Name="myTextBox" Style="{StaticResource stlHintbox}" /> 
    <Border Visibility="Hidden"> 
     <TextBlock x:Name="hintText" Text="{Binding Tag, ElementName=myTextBox}" FontStyle="Italic" Foreground="LightGray" /> 
    </Border> 
</StackPanel> 
+0

Questo è OK, ma mi impedisce di avere più di un hintbox nella stessa finestra, e il suo utilizzo non sarebbe così ovvio. Grazie per il suggerimento sui modelli di controllo, vedrò di più ... – veljkoz