【问题标题】:Hierarchical Datatemplate Binding To DataType Not DataContext分层数据模板绑定到 DataType 而不是 DataContext
【发布时间】:2012-02-09 18:40:16
【问题描述】:

我有一个用户控件,里面有一棵树,命令属性绑定到 DataType 而不是 DataContext。

如何将绑定重定向到 DataContext 而不是 DataType ?另外出于好奇,我将如何绑定到 UserControl 的 DataContext 而不是 Tree 的 DataContext ?

这里是有问题的代码:

<HierarchicalDataTemplate 
            DataType="{x:Type viewModel:UsersViewModel}" 
            ItemsSource="{Binding Children}"
            >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding UserName}">
                    <TextBlock.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Edit" Command="{Binding EditCommand}" CommandParameter="{Binding UserName}"/>
                                <MenuItem Header="Delete"/>
                            </ContextMenu>
                        </TextBlock.ContextMenu>
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>

它似乎绑定到 UsersViewModel 而不是 DataContext(AllUsersViewModel)。

这是整个 XAML 以防万一:

 <Grid Width="150">
<TreeView ItemsSource="{Binding Users}" DataContext="{Binding allUsersViewModel}">
    <TreeView.ItemContainerStyle>
        <!-- 
    This Style binds a TreeViewItem to a TreeViewItemViewModel. 
    -->
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <Setter Property="FontWeight" Value="Normal" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="FontWeight" Value="Bold" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>

    <TreeView.Resources>    
        <ContextMenu x:Key="CategoryMenu">
            <MenuItem Header="Add Subcategory" Command="New">
            </MenuItem>

            <MenuItem Header="Remove Category" Command="Delete">
            </MenuItem>
        </ContextMenu>

        <HierarchicalDataTemplate 
            DataType="{x:Type viewModel:UsersViewModel}" 
            ItemsSource="{Binding Children}"
            >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding UserName}">
                    <TextBlock.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Edit" Command="{Binding EditCommand}" CommandParameter="{Binding UserName}"/>
                                <MenuItem Header="Delete"/>
                            </ContextMenu>
                        </TextBlock.ContextMenu>
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate 
            DataType="{x:Type viewModel:PermissionCategoryViewModel}" 
            ItemsSource="{Binding Children}"
            >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding PermissionCategoryName}" />
            </StackPanel>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="{x:Type viewModel:PermissionViewModel}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding PermissionName}" />
            </StackPanel>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>
</Grid> 

感谢您的帮助!

编辑

好吧,我尝试了一些方法,但没有成功 =(。什么都没有发生

我应该提到我的 MainWindow 具有 DataContext 并且 UserControl 通过将 UserControl 放置在其中来继承它。

<Window.DataContext>
    <viewModel:MainViewModel/>
</Window.DataContext>

我尝试了这些不同的东西

Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:AllUsers}}, Path=DataContext.EditCommand}"

Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}, Path=DataContext.EditCommand}"

Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, Path=DataContext.EditCommand}"

Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AllUsers}}, Path=DataContext.EditCommand}"

最后

Command="{Binding PlacementTarget.DataContext.EditCommand, 
                      RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"

【问题讨论】:

    标签: wpf xaml data-binding


    【解决方案1】:

    您可以使用RelativeSource 绑定来查找TreeView,然后绑定到它的DataContext

    Command="{Binding Path=DataContext.EditCommand,
        RelativeSource={RelativeSource AncestorType={x:Type TreeView}}}"
    

    如果您想绑定到您的 UserControl,您可以使用相同类型的绑定:

    RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}
    

    请注意,RelativeSource 绑定将返回对 UI 对象的引用,而不是 DataContext,因此如果要绑定到 DataContext 中的某些内容,则必须指定 Path=DataContext.SomeValue

    【讨论】:

    • 我在尝试了您的建议后编辑了我的帖子,但仍然无法正确处理 =(
    • @BatMasterson 查看我的编辑。我重新阅读了您的问题,并认为我了解您现在想要做什么。
    • 嗯,我正在尝试从 UserControl windows DataContext 中获取它。我会尝试一些事情并报告回来。感谢您迄今为止的帮助!
    • 我使用来自父母的标签计算出来,我会给你答案,因为它非常接近 =)~
    猜你喜欢
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 2011-05-19
    • 2011-01-23
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2010-11-29
    相关资源
    最近更新 更多