2009-05-15 5 views
15

Ho una serie di controlli TextBlock e TextBox. C'è un modo per applicare uno Style allo TextBlock in modo tale che possano accedere al controllo immediatamente dopo di essi?In WPF, c'è un modo per legarsi alle proprietà di pari livello?

mi piacerebbe essere in grado di fare qualcosa del genere:

<Resources..> 
    <Style x:Key="BindToFollowingTextBoxSibling"> 
     <Setter Property="TextBlock.Text" Value="{Binding RelativeSource={RelativeSource FollowingSibling}, Path=Text, Converter={StaticResource MyConverter}}" /> 
     <Setter Property="TextBlock.Background" Value="{Binding RelativeSource={RelativeSource FollowingSibling}, Path=Text, Converter={StaticResource TextToBrushConverter}}" /> 
     ... More properties and converters. 
    </Style> 
</Resources> 

... 

<TextBlock Style="{StaticResource BindToFollowingTextBoxSibling}"/> 
<TextBox/> 

<TextBlock Style="{StaticResource BindToFollowingTextBoxSibling}"/> 
<TextBox/> 
<TextBlock Style="{StaticResource BindToPreviousTextBoxSibling}"/> 

è qualcosa di simile anche possibile?

risposta

14

Penso che la cosa migliore da fare in questo caso è strettamente legato per ElementName:

<TextBlock Text="{Binding ElementName=textBox1, Path=Text}" /> 
<TextBox x:Name="textBox1">this is the textBox's 1 text</TextBox> 
<TextBlock Text="{Binding ElementName=textBox2, Path=Text}" /> 
<TextBox x:Name="textBox2">this is the textBox's 2 text</TextBox> 

Sarà ottenere qualcosa di simile. Per te funziona?

+0

Questo è il genere di quello che sto probabile intenzione di fare. Il problema è che ci sono diverse proprietà e convertitori che sto osservando come vincolanti, quindi diventa molto copia e passato per fare ciò per ogni proprietà. Penso che potrei associare ElementName al Tag di TextBlock e quindi utilizzare RelativeSource Self per ottenere le proprietà di cui ho bisogno. – Eclipse

+0

Questo ha mai funzionato per te? – Carlo

+0

Alla fine ho appena creato un controllo utente che gestiva i casi di cui avevo bisogno. Era solo più facile – Eclipse

19

So che questo è un thread precedente, ma ho trovato una soluzione a questo problema. Sono stato in grado di utilizzare il suggerimento di Aland Li, trovato here. Non è così generico come lo è nei CSS, ma se si conosce il tipo di elemento genitore, questo funziona bene anche in uno stile.

Ecco un esempio di come l'ho usato. Ho un controllo TextBox che si illumina con un "colore di evidenziazione" quando è attivo. Inoltre, volevo che il controllo Label associato si accendesse anche quando il TextBox era attivo. Così ho scritto un Trigger per il controllo Label che lo illuminava in modo simile a quello del controllo TextBox. Questo trigger viene attivato da una proprietà associata personalizzata denominata IsFocusedByProxy. Quindi avevo bisogno di associare IsFocusedByProxy dell'etichetta a IsFocused del TextBox. Così ho usato questa tecnica:

<Grid x:Name="MaxGrid"> 
    <Label x:Name="MaxLabel" 
      Content="Max:" 
      c5:TagHelper.IsFocusedByProxy="{Binding 
            Path=Children[1].IsFocused, 
            RelativeSource={RelativeSource AncestorType=Grid}}" 
     /> 
    <c5:TextBoxC5Mediator x:Name="MaxTextBox"       
          DataContext="{Binding ConfigVm.Max_mediator}" /> 
</Grid> 

A questo punto si potrebbe pensare che la sua non meglio di quanto usando solo ElementName nel legame. Ma la differenza è che ora posso spostare questo legame in uno stile per la riusabilità:

<Setter Property="C5_Behaviors:TagHelper.IsFocusedByProxy" 
     Value="{Binding Path=Children[1].IsFocused, 
        RelativeSource={RelativeSource AncestorType=Grid}}" /> 

e ora posso quando ho una visione completa di queste occorrenze, come questo (ho installato i necessari stili per essere applicata in modo implicito, è per questo che non c'è margine di profitto dimostrato che imposta le Styles):

<Grid x:Name="MaxGrid"> 
    <Label x:Name="MaxLabel" 
      Content="Max:" /> 
    <c5:TextBoxC5Mediator x:Name="MaxTextBox"       
          DataContext="{Binding ConfigVm.Max_mediator}" /> 
</Grid> 
<Grid x:Name="MinGrid"> 
    <Label x:Name="MinLabel" 
      Content="Min:" /> 
    <c5:TextBoxC5Mediator x:Name="MinTextBox"       
          DataContext="{Binding ConfigVm.Min_mediator}" /> 
</Grid> 
<Grid x:Name="StepFactorGrid"> 
    <Label x:Name="StepFactorLabel" 
      Content="Step Factor:" /> 
    <c5:TextBoxC5Mediator x:Name="StepFactorTextBox"       
          DataContext="{Binding ConfigVm.StepFactor_mediator}" /> 
</Grid> 
<!-- ... and lots more ... --> 

che mi dà questi risultati:

Prima di qualsiasi testo Scatole hanno messa a fuoco:

Before any TextBoxes have focus

con diverse caselle di testo che riceve attenzione:

after focus 1

after focus 2

+6

+1 per '{Binding Path = Children [1]. IsFocused, RelativeSource = {RelativeSource AncestorType = Grid}}'. –

+0

Quindi presumo che "1" in Path = Children [1] ... sia l'indice? Questo ha funzionato per me, ma volevo chiarire il significato del valore numerico. – EdwardM

+1

@EdwardM corretto, il '1' in' Percorso = Bambini [1] 'è un indice (indice a base zero, ovviamente). Quindi potresti aggiustare quel numero se la tua struttura fosse diversa. Saluti. –

Problemi correlati