The XMLDataProvider might be a simpler option: How to: Bind to XML Data Using an XMLDataProvider and XPath Queries - WPF | Microsoft Docs[^] If you want to stick with code, you're going to need a class to represent the menu item. For example:
public class MenuHeaderItem
{
public string HeaderName { get; set; }
public IReadOnlyList<MenuHeaderItem> Children { get; set; }
}
public static IReadOnlyList<MenuHeaderItem> LoadMenu(XDocument document)
{
var result = new List<MenuHeaderItem>();
var allHeaders = document.Descendants("Header");
foreach (XElement node in allHeaders)
{
result.Add(new MenuHeaderItem
{
HeaderName = (string)node.Attribute("Value"),
Children = node.Elements().Select(el => new MenuHeaderItem
{
HeaderName = (string)el,
}).ToList(),
});
}
return result;
}
Bind the loaded values to a read-only dependency property:
private static readonly DependencyPropertyKey MenuHeadersKey = DependencyProperty.RegisterReadOnly(
"MenuHeaders",
typeof(IReadOnlyList<MenuHeaderItem>),
typeof(YourContainingClass),
new PropertyMetadata(null)
);
public static readonly DependencyProperty MenuHeadersProperty = MenuHeadersKey.DependencyProperty;
public IReadOnlyList<MenuHeaderItem> MenuHeaders
{
get { return (IReadOnlyList<MenuHeaderItem>)GetValue(MenuHeadersProperty); }
private set { SetValue(MenuHeadersKey, value); }
}
private void LoadHeaders()
{
if (File.Exists("MenuHeaders.xml"))
{
XDocument document = XDocument.Load("MenuHeaders.xml");
MenuHeaders = LoadMenu(document);
}
}
Then bind the MenuHeaders collection to your menu.
<Menu ItemsSource="{Binding Path=MenuHeaders}">
<Menu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Path=HeaderName}" />
<Setter Property="ItemsSource" Value="{Binding Path=Children}" />