Если DataTemplate вложен в другой Datatemplate, трудно связать со свойством отца-шаблона - PullRequest
0 голосов
/ 02 февраля 2012

Знаете ли вы, что проблема неоднократно обсуждалась в Интернете. Но у меня особый случай, и я до сих пор не нашел правильного решения.

Сценарий: 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}, Mode = 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" - ничто, тогда у меня нет Визуальное дерево для прокрутки .

У вас есть предложение? Заранее спасибо! Pileggi

Ответы [ 2 ]

1 голос
/ 03 февраля 2012

Я бы предложил передать ссылку на вашу модель родительского представления дочерним элементам в процессе строительства:

var itemVm = new ItemViewModel()
{
    Description = "Parent", ChildVisibility = "Collapsed"
}
itemVm.Children = new List<ChildItemViewModel>
{
    new ChildItemViewModel()
    {
        ParentVm = itemVm;
        Description = "Child"
    }
}

Таким образом вы можете легко связать свойство в модели родительского представления следующим образом:

<TextBlock Visibility="{Binding ParentVM.ChildVisibility}"/>
0 голосов
/ 03 февраля 2012

Если вы не хотите использовать решение eric (чтобы вы добавили одно и то же свойство родителя в дочерний класс), я полагаю, что единственный способ, которым вы можете воспользоваться, - это обновить приложение до Silverlight.5, которые поддерживают FindAncestor с RelativeSource:

Visibility = "{Binding DataContext.Ori, Converter = {StaticResource rVisibilityConverter}, RelativeSource = {RelativeSource AncestorLevel = 2, AncestorType = {x: Тип TreeViewItemst}, режим = FindA}} "

...