Mam zestaw kontrolek z dołączonymi poleceniami i logiką, które są stale ponownie używane w ten sam sposób. Zdecydowałem się stworzyć kontrolkę użytkownika, która zawiera wszystkie wspólne kontrolki i logikę.
Jednak potrzebuję również kontrolki, aby móc przechowywać zawartość, którą można nazwać. Wypróbowałem następujące:
<UserControl.ContentTemplate>
<DataTemplate>
<Button>a reused button</Button>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Button>a reused button</Button>
</DataTemplate>
</UserControl.ContentTemplate>
Jednak wydaje się, że nie można nazwać żadnej zawartości umieszczonej w kontrolce użytkownika. Na przykład, jeśli używam kontrolki w następujący sposób:
<lib:UserControl1>
<Button Name="buttonName">content</Button>
</lib:UserControl1>
Otrzymuję następujący błąd:
Nie można ustawić wartości atrybutu nazwy „buttonName” w elemencie „Button”. „Przycisk” znajduje się w zakresie elementu „UserControl1”, który miał już zarejestrowaną nazwę, gdy została zdefiniowana w innym zakresie.
Jeśli usunę buttonName, zostanie on skompilowany, ale muszę mieć możliwość nazwania zawartości. Jak mogę to osiągnąć?
Odpowiedzi:
Odpowiedź brzmi: nie używaj do tego UserControl.
Utwórz klasę, która rozszerza ContentControl
następnie użyj stylu, aby określić zawartość
i wreszcie - użyj go
źródło
UserControl
na dziedziczenieContentControl
. Aby rozwiązać, po prostu dodaj nową klasę ( nie XAML z CS). I wtedy (miejmy nadzieję) zadziała. jeśli chcesz, stworzyłem małe rozwiązanie VS2010HeadingContainer
iMyFunkyContainer
tak powinno byćMyFunkyControl
?!Wydaje się, że nie jest to możliwe, gdy używany jest język XAML. Niestandardowe kontrolki wydają się przesadą, kiedy faktycznie mam wszystkie potrzebne kontrolki, ale wystarczy zgrupować je razem z odrobiną logiki i zezwolić na nazwane treści.
Rozwiązanie na blogu JD, jak sugeruje mackenir, wydaje się mieć najlepszy kompromis. Sposób na rozszerzenie rozwiązania JD, aby umożliwić dalsze definiowanie formantów w języku XAML, może wyglądać następująco:
W powyższym przykładzie utworzyłem kontrolkę użytkownika o nazwie UserControlDefinedInXAML, która jest zdefiniowana jak każda normalna kontrolka użytkownika przy użyciu XAML. W moim UserControlDefinedInXAML mam StackPanel o nazwie aStackPanel, w którym chcę, aby pojawiła się moja nazwana zawartość.
źródło
Inną alternatywą, której użyłem, jest po prostu ustawienie
Name
właściwości wLoaded
zdarzeniu.W moim przypadku miałem dość złożoną kontrolkę, której nie chciałem tworzyć w kodzie, i szukała ona opcjonalnej kontrolki o określonej nazwie dla określonego zachowania, a ponieważ zauważyłem, że mogę ustawić nazwę w
DataTemplate
Pomyślałem, że mogę to zrobić również wLoaded
przypadku.źródło
Czasami wystarczy odwołać się do elementu z C #. W zależności od przypadku użycia można następnie ustawić
x:Uid
zamiast anx:Name
i uzyskać dostęp do elementów, wywołując metodę Uid Finder, taką jak Get object według jego Uid w WPF .źródło
Możesz użyć tego pomocnika do ustawienia nazwy w kontrolce użytkownika:
a Twój Window lub Control Code Behind ustawia kontrolę według właściwości:
twoje okno xaml:
UserControlNameHelper uzyskuje nazwę kontrolki i nazwę klasy, aby ustawić kontrolę na Właściwość.
źródło
Zdecydowałem się utworzyć dodatkową właściwość dla każdego elementu, który potrzebuję:
Umożliwia mi to dostęp do elementów podrzędnych w XAML:
źródło
Kod za:
Prawdziwym rozwiązaniem byłoby naprawienie tego problemu przez Microsoft, a także wszystkich innych z uszkodzonymi drzewami wizualnymi itp. Hipotetycznie.
źródło
Jeszcze jedno obejście: odwołaj się do elementu jako RelativeSource .
źródło
Miałem ten sam problem, używając TabControl podczas umieszczania zestawu nazwanych kontrolek w.
Moje obejście polegało na użyciu szablonu kontrolnego, który zawiera wszystkie moje kontrolki, które mają być wyświetlane na stronie karty. Wewnątrz szablonu można użyć właściwości Name, a także powiązać dane z właściwościami nazwanej kontrolki z innych kontrolek przynajmniej w tym samym szablonie.
Jako zawartość kontrolki TabItem użyj prostej kontrolki i odpowiednio ustaw ControlTemplate:
Uzyskanie dostępu do nazwanej kontrolki w szablonie z kodu znajdującego się za Tobą wymagałoby użycia drzewa wizualnego.
źródło