在绑定到集合的数据的WPF菜单中,我可以正确地设置所有内容,但使用键盘导航不再按预期工作。
考虑下面的XAML(您可以将其粘贴到像KaXaml这样的工具中)。
两件事:
打开菜单并使用箭头键向右导航将默认选择打开的菜单项中的第一项。例如:
浏览子项目并不起作用。按右箭头时,将打开下一个顶级菜单项,而不是向下钻取到子项
如何确保'默认'使用键导航时的菜单行为?
这是您可以使用以下方法测试的XAML:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Menu VerticalAlignment="Top">
<MenuItem Header="One">
<MenuItem Header="A">
<MenuItem Header="I" />
<MenuItem Header="II" />
<MenuItem Header="III" />
</MenuItem>
<MenuItem Header="B"/>
<MenuItem Header="C"/>
</MenuItem>
<MenuItem Header="Two">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<MenuItem>
<MenuItem.HeaderTemplate>
<DataTemplate>
<TextBlock>
<Run Text="Bound property" />
</TextBlock>
</DataTemplate>
</MenuItem.HeaderTemplate>
<MenuItem Header="Something"/>
<MenuItem Header="Something else"/>
</MenuItem>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</MenuItem.ItemContainerStyle>
<MenuItem Header="A"/>
<MenuItem Header="B"/>
<MenuItem Header="C"/>
</MenuItem>
<MenuItem Header="Three">
<MenuItem Header="A">
<MenuItem Header="I" />
<MenuItem Header="II" />
<MenuItem Header="III" />
</MenuItem>
<MenuItem Header="B"/>
<MenuItem Header="C"/>
</MenuItem>
</Menu>
</Grid>
</Page>
更新
特别之处在于我的ControlTemplate中的子MenuItems应该为每个DataBound MenuItem添加。这是因为我有一个ObservableCollection,我将使用它在MenuItem&#34; Two&#34;中构建MenuItems。对于这些MenuItem中的每一个,我需要相同的子MenuItems。除了CommandParameter之外,它们将绑定到每个MenuItem的相同Command。
所以我最终想要的是:
Two
Bound property 1
Something
Something else
Bound property 2
Something
Something else
Bound property 3
Something
Something else
答案 0 :(得分:2)
您不应在MenuItem
的模板中创建MenuItem
元素。您应该为项目设置样式,使其具有绑定的内容。
我已经添加了XML作为菜单项的源,因此“Two”项目的内容绑定到XML(您可以将其替换为您的集合)。对于此解决方案,您应该有一个子菜单项的集合(一个用于所有顶级项目,而不是每个顶级项目)。键盘导航在以下示例中正常工作。
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<XmlDataProvider x:Key="MenuProvider" XPath="Items">
<x:XData>
<Items xmlns="">
<Item Title="Bound property 1" Parameter="1" />
<Item Title="Bound property 2" Parameter="2" />
<Item Title="Bound property 3" Parameter="3" />
</Items>
</x:XData>
</XmlDataProvider>
<XmlDataProvider x:Key="SubMenuProvider" XPath="Items">
<x:XData>
<Items xmlns="">
<Item Title="Something" />
<Item Title="Something else" />
</Items>
</x:XData>
</XmlDataProvider>
</Page.Resources>
<Grid>
<Menu VerticalAlignment="Top">
<MenuItem Header="One">
<MenuItem Header="A">
<MenuItem Header="I" />
<MenuItem Header="II" />
<MenuItem Header="III" />
</MenuItem>
<MenuItem Header="B" />
<MenuItem Header="C" />
</MenuItem>
<MenuItem Header="Two" ItemsSource="{Binding Source={StaticResource MenuProvider}, XPath=*}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding XPath=@Title}" />
<Setter Property="ItemsSource" Value="{Binding Source={StaticResource SubMenuProvider}, XPath=*}" />
<Setter Property="Tag" Value="{Binding XPath=@Parameter}" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding XPath=@Title}" />
<Setter Property="CommandParameter" Value="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType=MenuItem}}" />
</Style>
</Setter.Value>
</Setter>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="Three">
<MenuItem Header="A">
<MenuItem Header="I" />
<MenuItem Header="II" />
<MenuItem Header="III" />
</MenuItem>
<MenuItem Header="B" />
<MenuItem Header="C" />
</MenuItem>
</Menu>
</Grid>
</Page>
答案 1 :(得分:1)
我确实重新设定了菜单项Two
,同时保留了您的预期需求
<MenuItem Header="Two">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header"
Value="Bound property" />
<Setter Property="ItemsSource">
<Setter.Value>
<!--binding sub menu items to a collection-->
<x:ArrayExtension Type="sys:String"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String>Something</sys:String>
<sys:String>Something else</sys:String>
</x:ArrayExtension>
</Setter.Value>
</Setter>
</Style>
</MenuItem.ItemContainerStyle>
<MenuItem />
<MenuItem />
<MenuItem />
</MenuItem>
上面的示例解决了导航问题,同时根据需要保持对子项的绑定。 试一试,看看它有多接近。