WPF MenuItem.Command绑定到ElementName结果到System.Windows.Data错误:4:无法找到带引用的绑定源

时间:2010-04-11 13:23:27

标签: wpf data-binding xaml

我有以下XAML:

<UserControl x:Class="EMS.Controls.Dictionary.TOCControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:EMS.Controls.Dictionary.Models"
    xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
    x:Name="root"  >

    <TreeView                    
        x:Name="TOCTreeView"                    
        Background="White"
         Padding="3,5"      
        ContextMenuOpening="TOCTreeView_ContextMenuOpening"
        ItemsSource="{Binding Children}" BorderBrush="{x:Null}"  >

        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=Children, Mode=OneTime}">
                <Grid >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <!--<ColumnDefinition Width="Auto"/>-->                       
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <!--<CheckBox VerticalAlignment="Center" IsChecked="{Binding IsVisible}"/>-->   
                    <ContentPresenter Grid.Column="0" Height="16" Width="20"
                                    Content="{Binding LayerRepresentation}"  />
                    <!--<ContentPresenter Grid.Column="1"      >
                        <ContentPresenter.Content>
                            Test
                        </ContentPresenter.Content>
                    </ContentPresenter>-->
                    <TextBlock Grid.Column="2" FontWeight="Normal" Text="{Binding Path=Alias, Mode=OneWay}" >
                        <ToolTipService.ToolTip>
                            <TextBlock Text="{Binding Description}" TextWrapping="Wrap"/>
                        </ToolTipService.ToolTip>
                    </TextBlock>
                </Grid>
                <HierarchicalDataTemplate.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Path=Children, Mode=OneTime}">
                        <!--<DataTemplate>-->
                        <Grid >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>                               
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <CheckBox VerticalAlignment="Center" IsChecked="{Binding IsVisible}"/>
                            <ContentPresenter Grid.Column="1"
                                    Content="{Binding LayerRepresentation, Mode=OneWay}"  />
                            <TextBlock Margin="0,1,0,1" Text="{Binding Path=Alias, Mode=OneWay}" Grid.Column="2">
                                <ToolTipService.ToolTip>
                                    <TextBlock Text="{Binding Description}" TextWrapping="Wrap"/>
                                </ToolTipService.ToolTip>                   
                            </TextBlock>
                        </Grid>
                        <!--</DataTemplate>-->
                    </HierarchicalDataTemplate>                  
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate> 

        <TreeView.ContextMenu>
            <ContextMenu>
                <MenuItem Name="miRemove" Header="Remove"
                          Command="{Binding ElementName=root, Path=RemoveItemCmd, 
                    diagnostics:PresentationTraceSources.TraceLevel=High}">
                    <MenuItem.Icon>
                        <Image Source="../images/16x16/Delete.png"/>
                    </MenuItem.Icon>
                </MenuItem>
                <MenuItem Header="Properties"
                          Command="{Binding ElementName=root, Path=GetItemPropertiesCmd}"/>               
            </ContextMenu>       
        </TreeView.ContextMenu>


    </TreeView>

</UserControl>

此UserControl后面的代码有两个ICommand属性,名称为:RemoveItemCmd和GetItemPropertiesCmd。但是,我得到了

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=root'. BindingExpression:Path=RemoveItemCmd; DataItem=null; target element is 'MenuItem' (Name='miRemove'); target property is 'Command' (type 'ICommand')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=root'. BindingExpression:Path=GetItemPropertiesCmd; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand')

构建UserControl时。为什么这样,我该如何解决?

3 个答案:

答案 0 :(得分:18)

您无法使用上下文菜单中的元素名称进行绑定。上下文菜单与其放置目标之间的链接断开。你可以使用几个技巧绕过它......

  1. 将RoutedUICommands与UserControl上的命令绑定一起使用,则不需要绑定。
  2. 在上下文菜单的DataContext上使用放置目标绑定。这使您至少可以将上下文菜单中元素的数据上下文显示在上下文菜单中。

    DataContext =“{Binding RelativeSource = {RelativeSource Mode = Self},Path = PlacementTarget.DataContext}”

  3. (我认为这就是你想要的)你可以访问静态资源,ElementSpy允许你使用静态资源链接到窗口,这样你就可以使用事实上的ElementName绑定。

答案 1 :(得分:8)

此处的最佳解决方案ElementName Binding from MenuItem in ContextMenu

只需一行代码:

NameScope.SetNameScope(contextMenu, NameScope.GetNameScope(this));

答案 2 :(得分:5)

使用.NET 4.0,您可以这样做:

<MenuItem Command="{Binding CommandName, Source={x:Reference ElementName}}"/>