I have a main menu mnuMainMenu
consisting of several sub-menus. One of the sub-menus mnuMostRecentDirs
is itself another menu that has it's items generated at run time, using the ItemSource property bound to an ObservableCollection. Basically it's displaying a list of the most recently used folders.
The issue is that the MenuItems added dynamically generate the following data binding error:
The XAML declaration of the main menu goes something like this:
<!-- 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>
And the following code adds folders to the observable collection at run time:
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);
}
}
I was able to trace the problem to a binding declared in the style for MenuItem which is not declared in my application. I assume it's the default style for menu items..
None of the other menu items appear to be having any binding problems with the same style being applied to all.
So I'm thinking that the problem must be my approach to adding the MenuItems dynamically. More specifically it seems that the style is being applied to the MenuItem before the item is added to the ItemsControl.
So far I could only come up with setting the HorizontalContentAlignment property in code, on the MenuItem before adding it to the observable collection, but that is just a band-aid and it's only really masking the real problem.
I really think it's not a good idea or ""WPF compatible"" to add UIelemnts from code.
I would suggest something like this:
and set MainMenu's ItemsSource to
MostRecentFoldersList
As pointed out by @LPL - it turns out this is a known (acknowledged) problem in the WPF framework. Based on information found on MSDN support forums here and here, it appears that when setting the ItemsSource of a MenuItem to a collection of MenuItems it doesn't handle things in the correct order
Per MSDN Support staff:
I hope this helps others having the same issue.