2013-03-07 11 views
11

Ho più TextBlock che fanno riferimento a diversi elementi nella mia applicazione. Il mio codice funziona correttamente se usato direttamente nella pagina. Tuttavia, voglio creare un ControlTemplate e un ContentControl per ridurre la duplicazione del codice.Come posso utilizzare un collegamento ElementName all'interno di ControlTemplate?

Come posso passare un riferimento a un ElementName nel ControlTemplate da ContentControl utilizzando TemplateBinding? Il codice seguente genera questo errore: ContentStringFormat

"Cannot convert the value in attribute 'ElementName' to object of type 'System.String'. Object of type 'System.Windows.TemplateBindingExpression' cannot be converted to type 'System.String'. "

Oltre all'attributo Tag, ho provato che, inoltre, non ha funzionato.

Qual è il metodo corretto per farlo funzionare con i modelli?

Grazie in anticipo per il vostro aiuto,

--- Shawn

Ecco il codice di esempio:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > 
    <Page.Resources> 
     <ControlTemplate x:Key="MyTemplate" TargetType="{x:Type ContentControl}"> 
      <TextBlock Margin="{Binding ElementName={TemplateBinding Tag}, Path=Margin}" Text="{TemplateBinding Content}" TextAlignment="{Binding ElementName={TemplateBinding Tag}, Path=TextAlignment}" Width="{Binding ElementName={TemplateBinding Tag}, Path=Width}" /> 
     </ControlTemplate> 
    </Page.Resources> 
    <StackPanel> 
     <TextBlock x:Name="AnotherElement" Margin="10" Text="Main TextBlock" TextAlignment="Center" Width="100" /> 
     <TextBlock x:Name="AnotherElement2" Margin="20" Text="Second TextBlock" TextAlignment="Left" Width="250" /> 
     <TextBlock Margin="{Binding ElementName=AnotherElement, Path=Margin}" Text="Here is my TextBlock!" TextAlignment="{Binding ElementName=AnotherElement, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement, Path=Width}" /> 
     <TextBlock Margin="{Binding ElementName=AnotherElement2, Path=Margin}" Text="Here is my Second TextBlock!" TextAlignment="{Binding ElementName=AnotherElement2, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement2, Path=Width}" /> 
     <ContentControl Content="Hello!" Tag="AnotherElement" Template="{StaticResource MyTemplate}" /> 
     <ContentControl Content="Hello Again!" Tag="AnotherElement2" Template="{StaticResource MyTemplate}" /> 
    </StackPanel> 
</Page> 
+1

Perché non creare stili e applicarli a tutti i controlli che richiedono tale stile? Perché vuoi definire alcune proprietà su un controllo e quindi associarvi altri controlli? Questo suona strano al meglio. –

+0

@Brent La memorizzazione delle informazioni in una proprietà Tag è stata utilizzata come tecnica con lo sviluppo di moduli MS Access. E 'stato un modo economico e sgradevole per passare qualche valore hardcoded a una funzione VBA legata a qualche proprietà/gestore sul tuo controllo. Non abbiamo bisogno di questo in WPF perché abbiamo a nostra disposizione una gamma più ampia di strumenti =) – failedprogramming

+0

@BrentStewart Il risultato finale di questa implementazione è la visualizzazione delle informazioni nelle colonne usando MVVM, Bindings, DataTemplates, ecc. per chiedere su questo sito. Ho scelto di non usare una griglia e invece di usare un WrapPanel perché ritenevo che fosse più facile e più pulito da usare. Sto legando diverse proprietà di un TextBlock a un altro perché voglio che il valore della mia colonna copi le proprietà che ho impostato per la sua intestazione specifica (margine, larghezza, allineamento, ecc.). Come implementeresti questo usando gli stili quando per ogni blocco di testo si farebbe riferimento a un diverso elementname? –

risposta

23

Questo mi sembra un modo divertente al modello qualcosa, ma può essere fatto, devi solo avere un po 'di fantasia con i tuoi attacchi.

Il sotto funzionerà, ma io continuo a non penso che questo è un buon modo al modello di un controllo

Bind il TextBlockTag al reale elemento, poi nel ControlTemplate legano Tag-Tag e utilizzare i valori da lì come Tag è l'elemento, puoi usare qualsiasi elemento da esso.

<Page.Resources> 
    <ControlTemplate x:Key="MyTemplate" TargetType="{x:Type ContentControl}"> 
     <TextBlock Name="_this" Tag="{TemplateBinding Tag}" Margin="{Binding ElementName=_this, Path=Tag.Margin}" Text="{TemplateBinding Content}" TextAlignment="{Binding ElementName=_this, Path=Tag.TextAlignment}" Width="{Binding ElementName=_this, Path=Tag.Width}" /> 
    </ControlTemplate> 
</Page.Resources> 
<StackPanel> 
    <TextBlock x:Name="AnotherElement" Margin="10" Text="Main TextBlock" TextAlignment="Center" Width="100" /> 
    <TextBlock x:Name="AnotherElement2" Margin="20" Text="Second TextBlock" TextAlignment="Left" Width="250" /> 
    <TextBlock Margin="{Binding ElementName=AnotherElement, Path=Margin}" Text="Here is my TextBlock!" TextAlignment="{Binding ElementName=AnotherElement, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement, Path=Width}" /> 
    <TextBlock Margin="{Binding ElementName=AnotherElement2, Path=Margin}" Text="Here is my Second TextBlock!" TextAlignment="{Binding ElementName=AnotherElement2, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement2, Path=Width}" /> 
    <ContentControl Content="Hello!" Tag="{Binding ElementName=AnotherElement}" Template="{StaticResource MyTemplate}" /> 
    <ContentControl Content="Hello Again!" Tag="{Binding ElementName=AnotherElement2}" Template="{StaticResource MyTemplate}" /> 
</StackPanel> 
+2

+1 per aver dichiarato che questo non è un buon metodo per creare un modello di controllo. –

+14

Grazie per la risposta. Funziona come voglio nella mia applicazione. Sia tu che @BrentStewart affermate che questo non è un buon modo per creare un modello di controllo. Secondo te, cos'è un buon modo e perché questo non è uno? –

+3

sì non ci sono alternative quindi, il suo tipo di sciocco per dire "non è un buon modo per farlo". Ovviamente, ma quali altre opzioni sono disponibili? A causa del modo in cui è progettato l'albero visivo, questo tipo di restrizione si presenta così spesso. – user99999991

Problemi correlati