如果 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:Type 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”方法中时,“AssociatedObject”的属性“Parent”什么都没有,然后我有没有可滚动的视觉树。
你有什么建议吗? 先感谢您! 皮莱吉
Have youI know that the problem has been many times discussed in the web. But mine is a particular case and I still haven't found the right solution.
Scenario: Silverlight 4 - A TreeView with data showed by two HierarchicalDataTemplate, one to show the first-level data (i.e. the data of the father-items of the TreeView), and one to show the second-level data (for the child-items). In the child-items template I have to bind the visibility of a control to a property of the data source class of the father template.
This is the XAML code:
<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>
If it was WPF I could write:
Visibility = "{Binding DataContext.Ori, Converter={StaticResource rVisibilityConverter}, RelativeSource={RelativeSource AncestorLevel=2, AncestorType={x:Type TreeViewItem}, Mode=FindAncestor}}"
... and it would certainly works. But I know that in Silverlight FindAncestor as binding-mode with RealitiveSource is not supported. The solutions in the web are all around the scrolling down, in the code-behind, of the visual tree. It doesn't matter if it's realized with a Behavior or with an Attached-Propery. The solutions are like this:
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>
I used many times solutions like this, and they always works. But in this case my DataTemplate is nested into another DataTemplate then, when I'm in the "OnAttached" method, the property "Parent" of the "AssociatedObject" is nothing, then I have no Visual-Tree to scroll.
Have you got a suggestion?
Thank you in advance!
Pileggi
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的建议是将父视图模型的引用传递给构造时的子视图:
通过这样做,您可以轻松绑定到父视图模型上的属性,如下所示:
My suggestion would be to pass a reference to your parent view model to the children on construction:
By doing so, you can easily bind to the property on the parent view model like so:
如果您不想使用 eric 解决方案(这会强制您在子类中添加父级的相同属性),我想您可以采取的唯一方法是将您的应用程序升级到 Silverlight 5,即支持FindAncestor与RelativeSource:
Visibility =“{Binding DataContext.Ori,Converter={StaticResource rVisibilityConverter},RelativeSource={RelativeSource AncestorLevel=2, AncestorType={x:Type TreeViewItem}, Mode=FindAncestor}}"
If you don't want to use the eric solution (taht force you to add the same property of the parent in the child class), the only way, I suppose, you can take, is to upgrade your application to Silverlight 5, that support FindAncestor with RelativeSource:
Visibility = "{Binding DataContext.Ori, Converter={StaticResource rVisibilityConverter}, RelativeSource={RelativeSource AncestorLevel=2, AncestorType={x:Type TreeViewItem}, Mode=FindAncestor}}"