【问题标题】:WPF MenuItem.Command binding to ElementName results to System.Windows.Data Error: 4 : Cannot find source for binding with referenceWPF MenuItem.Command 绑定到 ElementName 结果到 System.Windows.Data 错误:4:无法找到绑定源
【发布时间】:2011-02-06 17:02:10
【问题描述】:

我有以下 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 错误:4:找不到与引用“ElementName = root”绑定的源。 BindingExpression:Path=RemoveItemCmd;数据项=空;目标元素是“MenuItem”(名称=“MIRemove”);目标属性是“命令”(类型“ICommand”) System.Windows.Data 错误:4:找不到与引用“ElementName = root”绑定的源。 BindingExpression:Path=GetItemPropertiesCmd;数据项=空;目标元素是'MenuItem'(名称='');目标属性是“命令”(类型“ICommand”)

在构造 UserControl 时。为什么会这样?我该如何解决?

【问题讨论】:

    标签: wpf data-binding xaml


    【解决方案1】:

    您不能使用上下文菜单中的元素名称进行绑定。上下文菜单与其放置目标之间的链接断开。不过,您可以使用一些技巧来解决它...

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 有时它会给你参考循环异常。
      • 刚试过这个,它会抛出一个空引用异常?
      • 我有空引用异常,并且取决于我在哪里使用它的循环异常。该死的。
      【解决方案3】:

      这里是最佳解决方案ElementName Binding from MenuItem in ContextMenu

      只有一行代码:

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

      【讨论】:

      • 最佳解决方案确实!非常感谢你让我头疼!干杯。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 2012-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-08
      相关资源
      最近更新 更多