【问题标题】:WPF DataTemplate using same DataContext like parent controlWPF DataTemplate 使用与父控件相同的 DataContext
【发布时间】:2013-07-14 11:14:26
【问题描述】:

我对 WPF 中的 DataContext 问题感到疯狂。我在 StackOverflow 中阅读了 cmets,但无法修复它。

我有以下数据模板:

<DataTemplate  x:Key="TodoTemplate"  >
    <Grid Margin="5 10 10 5" >

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30" MaxWidth="30"/>
            <ColumnDefinition Width="30" MaxWidth="30"/>
            <ColumnDefinition Width="30" MaxWidth="30"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Grid.ContextMenu>
            <ContextMenu>
                <MenuItem Command="{Binding Path=View}">
                    <MenuItem.Header>
                        <WrapPanel>
                            <Label Margin="30 0 0 0" Background="LightBlue">View Item</Label>
                        </WrapPanel>
                    </MenuItem.Header>
                </MenuItem>

还有一个我想重用模板的列表框:

    <ListBox Grid.Row="4" ItemsSource="{Binding Path=Items}" Margin="10" ItemTemplateSelector="{StaticResource categoryItemSelector}" SelectedItem="{Binding Path=CurrentItem,Mode=TwoWay}" MouseDoubleClick="ListBox_MouseDoubleClick"  >

    </ListBox>

Listbox 代码嵌入在页面中,该页面为视图模型实例设置 DataContext。

  DataContext="{Binding Source={StaticResource Locator},Path=CategoryDetails}">

我了解到上下文菜单不是可视化树的一部分,并且不能直接重用数据上下文。问题是,我也有一个带有相同上下文菜单的 MemoTemplate,我想在这里重用我的视图模型。谁能给我一个提示来解决它?

我尝试使用 ContextService 参数并设置代理。但是我的 View 命令不是通过上下文菜单调用的。

我如何在此处重用我的页面(通过列表框)中的视图模型实例?

提前致谢 比约恩

【问题讨论】:

    标签: wpf viewmodel datatemplate datacontext


    【解决方案1】:

    您甚至可以从ContextMenu 引用DataContext。只需使用PlacementTarget 路由您的Binding

    不确定你在哪里声明了这个 View 命令,所以我将描述这两种方法。

    1: View命令属于ListBoxItemSource类型T(换句话说,它在构成ListBox的子元素的类中)

    非常简单,我们将ContextMenuDataContext 设置为与PlacementTarget 相同,即Grid

    ...
    <Grid.ContextMenu>
      <ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext}">
        <MenuItem Command="{Binding Path=View}">
          <MenuItem.Header>
        ...
    

    2:如果View 命令在VM 中CategoryDetails 作为Items 属性的兄弟。

    通过这种方法,我们将ListBox(即CategoryDetails VM)的DataContext 设置为ContextMenu 附加到的Grid 元素的Tag。现在在ContextMenu 中,我们将MenuItem.Command 绑定到ContextMenuPlacementTarget.Tag.View

    ...
    <Grid Margin="5 10 10 5"
                  Tag="{Binding RelativeSource={RelativeSource FindAncestor,
                                                               AncestorType={x:Type ListBox}},
                                Path=DataContext}">
              <Grid.ContextMenu>
                <ContextMenu>
                  <MenuItem Command="{Binding Path=PlacementTarget.Tag.View, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}">
    ...
    

    如果您不想为此使用Tag,可以将Tag 替换为附加属性。

    【讨论】:

    • 我明白了,诀窍是从我的列表框中绑定到附加属性(如标记),然后再从我的菜单项绑定到上下文菜单。
    猜你喜欢
    • 1970-01-01
    • 2015-06-27
    • 2015-07-01
    • 2021-12-21
    • 2011-11-27
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    相关资源
    最近更新 更多