【问题标题】:MenuItem added programmatically causes Binding error以编程方式添加的 MenuItem 导致绑定错误
【发布时间】:2013-01-25 16:44:25
【问题描述】:

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

问题是添加的 MenuItems 动态生成以下数据绑定错误:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')

主菜单的 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 样式声明的绑定。我认为这是菜单项的默认样式..

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

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

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

【问题讨论】:

  • 请看answer here
  • @LPL - 感谢您发布该链接。不过你应该把它作为答案..

标签: wpf binding styles


【解决方案1】:

正如@LPL 所指出的 - 事实证明这是 WPF 框架中的一个已知(已确认)问题。根据在 MSDN 支持论坛 herehere 上找到的信息,似乎在将 MenuItem 的 ItemsSource 设置为 MenuItems 的集合时,它不会以正确的顺序处理事情

每位 MSDN 支持人员:

当您将 MenuItem.ItemsSource 设置为一个 Collection 时,就会发生这种情况 包含菜单项。这个错误已经在内部处理过了,所以 你可以别管它。

或者您可以显式设置 MenuItem.Horizo​​ntalContentAlignment 属性 和 VerticalContentAlignment 属性以避免此错误。你可以 只需将以下代码放入 application.Resource 即可实现。

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

我希望这可以帮助其他遇到同样问题的人。

【讨论】:

  • 和你完全一样的问题,非常烦人的绑定错误,但这暂时解决了。有人知道自 2013 年以来它是否已“修复”?!
【解决方案2】:

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

我会建议这样的事情:

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

并将 MainMenu 的 ItemsSource 设置为 MostRecentFoldersList

【讨论】:

  • 我同意你的观点,从哲学的角度来看,它不是 100% WPF。尽管如此,这种行为还是很奇怪,我试图了解导致它的原因以及将来如何能够更轻松地调试此类问题。
  • 从分层模型创建菜单层次结构并通过绑定修改菜单时出现相同的错误。这个问题没有解决,因为......它唯一令人讨厌的原因是我在调试模式下有一个绑定错误处理程序以调查绑定错误,并且每次我使用不同的用户登录时它都会停止......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多