2011-02-02 5 views
14

Se la persona che ha risposto this question ha ragione, non è possibile inserire un legame come valore in un setter in uno stile in Silverlight. Il che è un peccato, perché ho 4 blocchi di testo che usano tutti lo stesso binding per la loro proprietà Opacity. Esiste comunque, in un certo senso, "stilare" la loro proprietà Opacity in modo che tutti e quattro puntino allo stesso legame? Altrimenti, devo impostare singolarmente ciascuna proprietà Opacity. Nel mio caso è anche peggio - tutti e quattro condividono anche altri legami di proprietà, il che significa che ogni dichiarazione di TextBlock è abbastanza lunga, eppure sono tutti virtualmente uguali (i loro legami di proprietà, cioè). So che potrei impostare concisamente tutti i loro binding di proprietà condivise nel code-behind, ma mi piacerebbe una soluzione XAML se ce n'è una.Silverlight: come usare un binding in setter per uno stile (o un equivalente lavoro intorno)

Grazie!

+1

È possibile applicare il binding in Style Setter in WPF, quindi stai chiedendo solo informazioni su Silverlight? – baalazamon

+0

Ah, non me ne sono reso conto. Ho modificato la mia domanda per dire specificamente Silverlight. – JoeCool

risposta

11

Ecco come è fatto. Si utilizza un ContentControl e specificare un ControlTemplate per essa come una risorsa statica: -

<Grid.Resources> 
    <ControlTemplate x:Key="CommonTextBlock" TargetType="ContentControl"> 
     <TextBlock Opacity="{Binding SomeOpacity}" Text="{TemplateBinding Content}" /> 
    </ControlTemplate> 
<Grid.Resource> 
<ContentControl Content="{Binding SomeTextValue}" Template="{StaticResource CommonTextBlock}" /> 
<ContentControl Content="{Binding SomeOtherTextValue}" Template="{StaticResource CommonTextBlock}" /> 

Ora è possibile tappo come possono altre proprietà con attacchi a al modello di controllo che si desidera.

Questo approccio potrebbe essere esteso a Style: -

<Grid.Resources> 
    <ControlTemplate x:Key="CommonTextBlock" TargetType="ContentControl"> 
     <TextBlock Opacity="{Binding SomeOpacity}" Text="{TemplateBinding Content}" /> 
    </ControlTemplate> 
    <Style x:Key="CommonTextBlockStyle" TargetType="ContentControl"> 
     <Setter Property="Template" Value="{StaticResource CommonTextBlock}" /> 
     <Setter Property="Foreground" Value="Blue" /> 
    </Style> 
<Grid.Resource> 
<ContentControl Content="{Binding SomeTextValue}" Style="{StaticResource CommonTextBlockStyle}" /> 
<ContentControl Content="{Binding SomeOtherTextValue}" Style="{StaticResource CommonTextBlockStyle}" /> 
+0

Mi piace l'idea alla base di questo, ma sembra che TextBlock non abbia una proprietà Template. C'è qualcosa che sto sbagliando? – JoeCool

+0

Questa è una soluzione abbastanza carina che hai lì. –

+0

@JoeCool: mi spiace che gli elementi 'TextBlock' dovrebbero essere i controlli del contenuto. Modificato di conseguenza. (Sapevo che avrei dovuto tagliare la pasta senza modificare il codice piuttosto che digitare di nuovo il codice). – AnthonyWJones

1

In Silverlight: Beh ... sì, non si può fare una rilegatura. Qui ho usato una risorsa statica, (che probabilmente non soddisferà le tue esigenze). Questo è il più vicino che si otterrà senza fare i binding nel codice.

<UserControl x:Class="SilverlightApplication1.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:system="clr-namespace:System;assembly=mscorlib" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400" 
    Name="this" Tag="0.5"> 

    <UserControl.Resources> 
    <system:Double x:Key="opacity">0.5</system:Double> 
    <Style TargetType="TextBlock"> 
     <Setter Property="Opacity" Value="{StaticResource opacity}"/> 
    </Style> 
    </UserControl.Resources> 
    <StackPanel> 
    <TextBlock Text="ABC"/> 
    <TextBlock Text="DEF"/> 
    <TextBlock Text="GHI"/> 
    <TextBlock Text="JKL"/> 
    </StackPanel> 
</UserControl> 

EDIT: Bene, qui è in WPF comunque ...

Qui si va, in WPF:

<Window x:Class="WpfApplication8.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" 
     Name="MyWindow" Tag="0.5"> 
    <Window.Resources> 
    <Style TargetType="{x:Type TextBlock}"> 
     <Setter Property="Opacity" Value="{Binding ElementName=MyWindow, Path=Tag}"/> 
    </Style> 
    </Window.Resources> 
    <StackPanel> 
    <TextBlock Text="ABC"/> 
    <TextBlock Text="DEF"/> 
    <TextBlock Text="GHI"/> 
    <TextBlock Text="JKL"/> 
    </StackPanel> 
</Window> 

Naturalmente si può ottenere molto più creativo di questo . Inoltre, a seconda di come/quando/dove sono definiti i tuoi stili, a volte è più semplice farlo semplicemente in codice.

2

Verificare SetterValueBindingHelper in questo blog article e il supporto per Binding in stile setter è announced for SL5.

+0

Purtroppo questo è ancora un tipo di soluzione "aggiungi codice per risolvere il problema". – AnthonyWJones