2013-03-07 13 views
11

Mam wiele TextBlocks, które odwołują się do różnych elementów w mojej aplikacji. Mój kod działa poprawnie, gdy jest używany bezpośrednio na stronie. Jednak chcę utworzyć ControlTemplate i ContentControl, aby zmniejszyć duplikację kodu.Jak mogę użyć wiązania ElementName w ramach ControlTemplate?

Jak mogę przekazać odwołanie do elementu ElementName do ControlTemplate z ContentControl za pomocą TemplateBinding? Poniższy kod generuje ten błąd:

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

Oprócz atrybutu Tag, próbowałem ContentStringFormat który również nie działa.

Jaka jest właściwa metoda, aby to działało przy użyciu szablonów?

Z góry dzięki za pomoc,

--- Shawn

Oto przykładowy kod:

<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

Dlaczego nie tworzyć stylów i stosować je do wszystkich elementów sterujących, które wymagają tego stylu? Dlaczego chcesz zdefiniować jakąś właściwość na jednej kontrolce, a następnie powiązać z nią inne kontrolki? To brzmi w najlepszym wypadku dziwnie. –

+0

@Brent Przechowywanie informacji we właściwości Tag było techniką opracowywania formularzy MS Access. Był to tani i nieprzyjemny sposób przekazania niektórych zakodowanych wartości do funkcji VBA powiązanej z jakąś własnością/handler'em na twojej kontroli. Nie potrzebujemy tego w WPF, ponieważ mamy do dyspozycji szerszy wachlarz narzędzi =) – failedprogramming

+0

@BrentStewart Końcowym rezultatem tej implementacji jest wyświetlanie informacji w kolumnach przy użyciu MVVM, Bindings, DataTemplates itd. Skalowałem mój przykład specjalnie za pytanie na tej stronie. Zdecydowałem się nie używać siatki i zamiast tego używać WrapPanel, ponieważ czułem, że jest łatwiejsze i bardziej przejrzyste w użyciu. Łączę kilka właściwości jednego bloku TextBlock do drugiego, ponieważ chcę, aby moja wartość kolumny była kopiowana do właściwości ustawionych dla jej konkretnego nagłówka (margines, szerokość, wyrównanie itd.). Jak zaimplementowałbyś to używając stylów, gdy dla każdego bloku tekstowego odwoływałaby się do innej nazwy elementu? –

Odpowiedz

23

To wydaje się zabawny sposób do szablonu coś, ale może być zrobione, po prostu musisz mieć trochę ochoty na swoje wiązania.

poniżej będzie działać, ale wciąż nie sądzę że jest to dobry sposób, aby szablon kontrolę

związania nią TextBlockTag do rzeczywistego elementu, a następnie w bind ControlTemplateTag do Tag i używać wartości stamtąd jako Tag jest elementem, możesz użyć dowolnego elementu z niego.

<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 za stwierdzenie, że nie jest to dobry sposób na zestrojenie formantu. –

+14

Dziękuję za odpowiedź. Działa to tak, jak chcę tego w mojej aplikacji. Zarówno Ty, jak i @BrentStewart stwierdzacie, że nie jest to dobry sposób na zestrojenie kontroli. W twojej opcji, co jest dobrym sposobem i dlaczego to nie jest jeden? –

+3

tak, nie ma alternatywy, więc jest głupio powiedzieć "nie jest to dobry sposób na zrobienie tego". Oczywiście, ale jakie inne opcje są dostępne? Ze względu na sposób projektowania wizualnego drzewa tego rodzaju ograniczenia pojawiają się tak często. – user99999991

Powiązane problemy