Если DataTemplate вложен в другой Datatemplate, трудно связать с помощью свойства отца-шаблона.
Знаете ли вы, что проблема неоднократно обсуждалась в Интернете. Но у меня частный случай, и я до сих пор не нашел правильного решения.
Сценарий: Silverlight 4 - TreeView с данными, отображаемыми двумя HierarchicalDataTemplate, один для отображения данных первого уровня (т. Е. Данные родительских элементов TreeView), а другой для отображения данных второго уровня (для дочерних элементов. Предметы). В шаблоне дочерних элементов я должен связать видимость элемента управления со свойством класса источника данных шаблона отца.
Это код XAML:
<UserControl.Resources>
<HierarchicalDataTemplate x:Key="modTreeArtDataParts2">
<Grid>
<TextBlock
Visibility="{Binding ???}"/>
</Grid>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="modTreeArtDataParts"
ItemTemplate = "{StaticResource modTreeArtDataParts2}"
ItemsSource = "{Binding RicambiItemList}">
</HierarchicalDataTemplate>
</UserControl.Resources>
<Grid>
<TreeView
ItemTemplate = "{StaticResource modTreeArtDataParts}"
ItemsSource="{Binding RicambiList}"/>
</Grid>
Если бы это был WPF, я мог бы написать:
Visibility = "{Binding DataContext.Ori, Converter = {StaticResource rVisibilityConverter}, RelativeSource = {RelativeSource AncestorLevel = 2, AncestorType = {x: Тип TreeViewItem}, Режим = FindAncestor}}"
... и это, безусловно, работает. Но я знаю, что в Silverlight FindAncestor режим связывания с RealitiveSource не поддерживается. Решения в сети - это прокрутка вниз, внутри кода, визуального дерева. Не имеет значения, реализовано ли это с поведением или с привязанностью. Решения таковы:
Public Class hideTextBlockBehavior
Inherits Behavior(Of DependencyObject)
Protected Overrides Sub OnAttached()
MyBase.OnAttached()
Dim g As Grid = FindVisualParent(Of Grid)(AssociatedObject)
Dim o As customType = g.DataContext
If o.hide Then AssociatedObject.Visibility = Visibility.Collapsed
End Sub
Private Function FindVisualParent(Of parentItem As DependencyObject)(ByVal obj As DependencyObject) As parentItem
Dim objParent As DependencyObject = obj
While obj Is Nothing = False AndAlso TypeOf obj Is parentItem = False
obj = VisualTreeHelper.GetParent(obj)
End While
Return DirectCast(obj, parentItem)
End Function
End Class
<HierarchicalDataTemplate x:Key="modTreeArtDataParts2">
<Grid>
<TextBlock>
<i:Interaction.Behaviors>
<il:hideTextBlockBehavior/>
</i:Interaction.Behaviors>
</TextBlock>
</Grid>
</HierarchicalDataTemplate>
Я много раз использовал подобные решения, и они всегда работают. Но в этом случае мой DataTemplate вкладывается в другой DataTemplate, а затем, когда я нахожусь в методе "OnAttached", свойство "Parent" в "AssociatedObject" является ничем, и у меня нет Visual-Tree для прокрутки.
У вас есть предложение? Заранее спасибо! Pileggi
2 ответа
Мое предложение было бы передать ссылку на вашу модель родительского представления для детей на строительстве:
var itemVm = new ItemViewModel()
{
Description = "Parent", ChildVisibility = "Collapsed"
}
itemVm.Children = new List<ChildItemViewModel>
{
new ChildItemViewModel()
{
ParentVm = itemVm;
Description = "Child"
}
}
Таким образом, вы можете легко привязать свойство к модели родительского представления следующим образом:
<TextBlock Visibility="{Binding ParentVM.ChildVisibility}"/>
Если вы не хотите использовать решение eric (чтобы вы добавили одно и то же свойство родителя в дочерний класс), я полагаю, что единственный способ, которым вы можете воспользоваться, - это обновить приложение до Silverlight 5, чтобы поддержка FindAncestor с RelativeSource:
Visibility = "{Binding DataContext.Ori, Converter = {StaticResource rVisibilityConverter}, RelativeSource = {RelativeSource AncestorLevel = 2, AncestorType = {x: Тип TreeViewItem}, Режим =FindAncestor}}"