以编程方式添加的菜单项会导致绑定错误



我有一个主菜单mnuMainMenu由几个子菜单组成。其中一个子菜单mnuMostRecentDirs本身就是另一个菜单,它使用绑定到 ObservableCollection 的 ItemSource 属性在运行时生成了它的项。基本上,它显示最近使用的文件夹列表。

问题是添加的菜单项会动态生成以下数据绑定错误:

System.Windows.Data 错误: 4 : 找不到引用"RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1'"进行绑定的源。绑定表达式:路径=水平内容对齐;数据项=空;目标元素是"菜单项"(名称=");目标属性为"水平内容对齐"(类型为"水平对齐")

主菜单的 XAML 声明如下所示:

 <!-- Main Menu -->
 <Menu x:Name="mnuMainMenu" Height="Auto" IsMainMenu="True">
    <!--- ... more menu declarations before ... -->
    <MenuItem x:Name="mnuitemWorkDirs" Header="Directories">
       <MenuItem x:Name="mnuNewDir"
                 Header="New" 
                 Style="{StaticResource MenuItem}" 
                 Command="{x:Static cmds:Commands.NewDirectory}" />
       <MenuItem x:Name="mnuCurrentDir"
                 Header="Current" 
                 Style="{StaticResource MenuItem}"
                 Command="{x:Static cmds:Commands.CurrentDirectory}" />
       <MenuItem x:Name="mnuMostRecentDirs" 
                 Header="Recent Directories.."
                 Style="{StaticResource MenuItem}"
                 ItemsSource="{Binding ElementName=theMain, Path=MostRecentFoldersList}" />
    </MenuItem>
    <!--- ... more menu declarations after ... -->
 </Menu>

以下代码在运行时将文件夹添加到可观察集合:

    private void PopulateMostRecentFoldersList(string[] paths) 
    {
        MostRecentFoldersList.Clear();
        if (paths == null)
           return;
        foreach (var fullPath in paths)
        {                                        
            var mi = new MenuItem();
            mi.Command = Commands.ChooseWorkingDirectory;
            mi.CommandParameter = fullPath;
            string name = System.IO.Path.GetFileName(fullPath);
            mi.Header = name.ToUpper();                
            // removing this style completely
            //     or manually setting the HorizontalContentAlignment property here 
            //     prevents the binding error from happening
            mi.Style = (Style)FindResource("MenuItem");                    
            MostRecentFoldersList.Add(mi);
        }
    }

我能够将问题追溯到以 MenuItem 样式声明的绑定,该绑定未在我的应用程序中声明。我假设这是菜单项的默认样式。

其他菜单项似乎都没有任何绑定问题,将相同的样式应用于所有菜单项。

所以我认为问题一定是我动态添加菜单项的方法。更具体地说,在将项添加到 ItemsControl 之前,该样式似乎已应用于菜单项。

到目前为止,我只能在将 MenuItem 添加到可观察集合之前,在代码中设置 HorizontalContentAlign 属性,但这只是一个创可贴,它只是真正掩盖了真正的问题。

正如@LPL所指出的 - 事实证明,这是WPF框架中一个已知的(公认的)问题。根据在 MSDN 支持论坛上找到的信息,当将菜单项的项源设置为菜单项的集合时,它似乎没有按正确的顺序处理事情

每个 MSDN 支持人员:

当您将 MenuItem.ItemsSource 设置为一个集合时,会发生这种情况 包含菜单项。此错误已在内部处理,因此 你可以不管它。

或者,您可以显式设置 MenuItem.HorizontalContentAlign 属性 和"垂直内容对齐"属性以避免此错误。您可以 只需将以下代码放入应用程序中即可。实现这一目标的资源。

  <Style TargetType="MenuItem">
   <Setter Property="HorizontalContentAlignment" Value="Left"/>
   <Setter Property="VerticalContentAlignment" Value="Center"/>
  </Style>

我希望这有助于其他有同样问题的其他人。

我真的认为从代码中添加UIelemnts不是一个好主意或"WPF兼容"。

我会建议这样的事情:

    <Menu>
        <MenuItem Header="MainMenu" Name="sampleMenu">
            <MenuItem.ItemTemplate>
                <DataTemplate>
                    <MenuItem Header="{Binding Path=PathtoNameOfRecentDocObject}"/>
                </DataTemplate>
            </MenuItem.ItemTemplate>
        </MenuItem>
    </Menu>

并将主菜单的 ItemsSource 设置为 MostRecentFoldersList

相关内容

  • 没有找到相关文章

最新更新