如果DataTemplate嵌套在另一个Datatemplate中,则很难与father-template属性绑定

时间:2012-02-02 00:01:45

标签: silverlight nested datatemplate visualtreehelper findancestor

您是否知道该问题已多次在网上讨论过。但我的是一个特例,我仍然没有找到正确的解决方案。

场景: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:Type TreeViewItem},Mode = FindAncestor}}”

......它肯定会奏效。但我知道在Silverlight中 FindAncestor不支持与RealitiveSource的绑定模式。 Web中的解决方案都围绕着向下滚动,在代码隐藏中,在可视树中。无论是通过行为还是使用Attached-Propery实现它都无关紧要。解决方案是这样的:

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”方法时,“AssociatedObject”的属性“Parent”什么都没有,然后我有没有要滚动的可视树

你有什么建议吗? 先感谢您! Pileggi

2 个答案:

答案 0 :(得分:1)

我的建议是将对父视图模型的引用传递给构造中的子项:

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

通过这样做,您可以轻松地绑定到父视图模型上的属性,如下所示:

<TextBlock Visibility="{Binding ParentVM.ChildVisibility}"/>

答案 1 :(得分:0)

如果您不想使用eric解决方案(强制您在子类中添加父级的相同属性),我认为您可以采取的唯一方法是将您的应用程序升级到Silverlight 5,支持带有RelativeSource的FindAncestor:

Visibility =“{Binding DataContext.Ori,Converter = {StaticResource rVisibilityConverter},RelativeSource = {RelativeSource AncestorLevel = 2,AncestorType = {x:Type TreeViewItem},Mode = FindAncestor}}”