2009-05-15 5 views
15

Ich habe eine Reihe von TextBlock und TextBox Kontrollen. Gibt es eine Möglichkeit, eine Style auf die TextBlock s so anzuwenden, dass sie unmittelbar danach auf die Steuerung databinden können?Gibt es in WPF eine Möglichkeit, an gleichgeordnete Eigenschaften zu binden?

Ich möchte in der Lage sein, so etwas zu tun:

<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}"/> 

so etwas wie dies überhaupt möglich ist?

Antwort

14

Ich denke, das Beste, was in diesem Fall zu tun, indem Element binden wird:

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

Es etwas Ähnliches erreichen. Geht das für dich?

+0

Das ist irgendwie, was ich wahrscheinlich tun würde. Das Problem ist, dass es mehrere Eigenschaften und Konverter gibt, die ich für bindend halte, so dass es für jede Eigenschaft eine Menge Kopie und Vergangenheit ist, dies zu tun. Ich denke, dass ich durch ElementName an das Tag des TextBlocks binden und dann RelativeSource Self verwenden kann, um die Eigenschaften zu erhalten, die ich benötige. – Eclipse

+0

Hat das jemals für Sie funktioniert? – Carlo

+0

Ich habe am Ende nur ein Benutzer-Steuerelement erstellt, das die Fälle behandelt, die ich brauchte. Es war einfach einfacher. – Eclipse

19

Ich weiß, das ist ein alter Thread, aber ich habe eine Lösung für dieses Problem gefunden. Ich konnte Aland Lis Vorschlag verwenden, gefunden here. Es ist nicht so allgemein wie es in CSS ist, aber wenn Sie den Elternelementtyp kennen, funktioniert das gut sogar in einem Style.

Hier ist ein Beispiel, wie ich es benutzt habe. Ich habe ein TextBox-Steuerelement, das mit einer "Hervorhebungsfarbe" aufleuchtet, wenn es den Fokus hat. Außerdem wollte ich, dass das zugehörige Label-Steuerelement auch aufleuchtet, wenn die TextBox den Fokus hatte. Also habe ich einen Trigger für das Label-Steuerelement geschrieben, der es ähnlich wie das TextBox-Steuerelement erleuchtet hat. Dieser Trigger wird von einer benutzerdefinierten Eigenschaft namens IsFocusedByProxy ausgelöst. Dann musste ich den IsFocusedByProxy des Labels an IsFocused der TextBox binden. So habe ich diese Technik:

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

An dieser Stelle Sie, dass denken kann seine nicht besser als als nur Elementname in der Bindung verwenden. Aber der Unterschied, dass jetzt ich diese Bindung in eine Art für Wiederverwertbarkeit bewegen kann:

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

Und jetzt kann ich, wenn ich einen Blick voll von diesen Vorkommen haben, so (ich habe Setup die notwendigen Styles implizit angewendet werden, ist also, warum nicht, es gibt Markup gezeigt, dass die Styles setzt):

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

Was mich diese Ergebnisse gibt:

Vor jedem Text Boxen haben Fokus:

Before any TextBoxes have focus

Mit verschiedenen Textfelder den Fokus erhält:

after focus 1

after focus 2

+6

+1 für '{Binding Path = Kinder [1] .IsFocused, RelativeSource = {RelativeSource AncestorType = Grid}}'. –

+0

Also nehme ich die "1" in Path = Kinder [1] ... ist der Index? Das hat bei mir funktioniert, wollte aber die Bedeutung des Zahlenwertes verdeutlichen. – EdwardM

+1

@EdwardM Korrekt, die '1' in' Path = Children [1] 'ist ein Index (natürlich nullbasierter Index). Sie könnten diese Zahl also anpassen, wenn Ihre Struktur anders wäre. Prost. –

Verwandte Themen