2010-09-03 11 views
13

Próbowałem utworzyć pole tekstowe z podpowiedzią wyświetlaną, gdy jest pusta. Mam problem z ustawieniem tekstu podpowiedzi w stylu.WPF Powiąż właściwość nadrzędną z elementu zagnieżdżonego, używając stylu

Aby być precyzyjnym, to działa (to znaczy, że wiąże się poprawnie):

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

ale kiedy przenieść je do stylu, to nie:

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

Więc jaki jest haczyk? Jak powiązać właściwość przodka z poziomu stylu?

Odpowiedz

12

Problem nie jest z RelativeSource ale ze sposobu korzystania z VisualBrush. Przypomnij sobie, że style są współużytkowane przez elementy, do których je zastosujesz. Powód, dla którego twój przykład nie działa, polega na tym, że próbujesz udostępnić pojedyncze pole tekstowe (oznaczone jako "wewnętrzne") w wielu nadrzędnych polach tekstowych.

Aby zobaczyć, dlaczego jest to problem, spróbuj eksperyment myślowy: Wewnętrzny pole tekstowe zostanie utworzone raz (w przybliżeniu, stanie się to po utworzeniu stylu). Które z pól tekstowych, do których zostanie zastosowany styl, powinno zostać wybrane jako przodek wewnętrznego pola tekstowego podczas używania wiązania RelativeSource?

To dlatego DataTemplates i ControlTemplates istnieją w WPF. Zamiast bezpośrednio tworzyć instancje wizualne, definiują szablon umożliwiający tworzenie wielu kopii wizualizacji w razie potrzeby.

+0

OK, to naprawdę ma sens ... Zbyt szybko przeszedłem przez książki :) – veljkoz

5

Reativesource nie działa zgodnie z oczekiwaniami. Lepiej jest utworzyć pole tekstowe ze znakiem wodnym za pomocą szablonu sterowania. Ale Twoja wersja może pracować:

<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

To jest OK, ale uniemożliwia mi posiadanie więcej niż jednej konsoli w tym samym oknie, a jej użycie nie byłoby tak oczywiste. Dzięki za sugestię na temat szablonów kontrolnych, zajrzę w to więcej ... – veljkoz

Powiązane problemy