我正在尝试设置一个 MenuItem
,它将有一个可以选择的页码子菜单。我想将 ItemsSource
绑定(bind)到页码列表(实际上是使用创建列表的转换器绑定(bind)到 PageCount),然后绑定(bind)每个 MenuItem 的
在 PageIndex 的子菜单中。我的问题是第二个绑定(bind),因为它也需要一个转换器,但该转换器需要知道 IsChecked
属性MenuItem
代表的页码,但我不知道如何将该信息传递给转换器。到目前为止,这是我尝试过的方法。
<MenuItem Header="_Goto Page"
ItemsSource="{Binding
Path=CurrentImage.PageCount,
Converter={StaticResource countToList}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="IsCheckable"
Value="True"/>
<Setter Property="IsChecked"
Value="{Binding
ElementName=MainWindow,
Path=CurrentImage.PageIndex,
Mode=TwoWay,
Converter={StaticResource pageNumChecked},
ConverterParameter={Binding
RelativeSource={RelativeSource Self},
Path=Content}}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
当然,问题是 ConverterParameter
不能绑定(bind),因为它不是 DependencyProperty
。所以我的问题是如何传递我需要的信息,或者有其他方法可以做到这一点。
注意:我已经尝试将 MenuItem
放入 ListBox
中,就绑定(bind)而言效果非常好,但会导致子菜单的行为以一种非标准的方式。也就是说,当您打开子菜单时,整个 ListBox
都被视为一个 MenuItem
。
编辑
这就是我到目前为止所做的工作。我尝试绑定(bind)到隐藏的 ListBox
但是当我将 MenuItem.ItemsSource
绑定(bind)到“ListBox.Items”时,我得到了 int
的列表而不是我需要获取 IsSelected
属性的 ListBoxItem
列表。因此,我最终采用了 Quartermeister 的建议,即使用 MultiBinding 获取 IsChecked
属性以在 OneWay
模式下绑定(bind)到 PageIndex
。为了处理另一个方向,我在 Click
事件上使用了一个事件处理程序。值得注意的是,起初我将 IsCheckable
设置为 true
并使用 Checked
事件,但结果是一些奇怪的行为。
<MenuItem x:Name="GotoPageMenuItem" Header="_Goto Page"
ItemsSource="{Binding Path=CurrentImage.PageCount,
Converter={StaticResource countToList}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="IsCheckable"
Value="False"/>
<EventSetter Event="Click"
Handler="GotoPageMenuItem_Click"/>
<Setter Property="IsChecked">
<Setter.Value>
<MultiBinding Converter="{StaticResource pageNumChecked}"
Mode="OneWay">
<Binding RelativeSource="{RelativeSource FindAncestor,
AncestorType={x:Type Window}}"
Path="CurrentImage.PageIndex"
Mode="OneWay"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="Header"
Mode="OneWay"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
这是 GotoPageMenuItem_Click
代码
private void GotoPageMenuItem_Click(object sender, RoutedEventArgs e)
{
var item = sender as MenuItem;
if (item != null)
{
//If the item is already checked then we don't need to do anything
if (!item.IsChecked)
{
var pageNum = (int)item.Header;
CurrentImage.PageIndex = (pageNum - 1);
}
}
}
最佳答案
听起来您正在尝试构建动态菜单来控制每个菜单项的选中状态。
我扩展了我编写的一些代码,以使用 MVVM 模式在 WPF 中构建动态菜单,并添加了检查逻辑。
这是 XAML:
<Menu DockPanel.Dock="Top">
<MenuItem ItemsSource="{Binding Commands}"
Header="_Item Container Style">
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="IsCheckable" Value="True"/>
<Setter Property="IsChecked" Value="{Binding Path=Checked}"/>
<Setter Property="Header" Value="{Binding Path=Text}" />
<Setter Property="Command" Value="{Binding Path=Command}" />
<Setter Property="CommandParameter" Value="{Binding Path=Parameter}" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</Menu>
这是 View 模型:
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
GoCommand = new DelegateCommand<object>(OnGoCommand, CanGoCommand);
LoadCommands();
}
private List<MyCommand> _commands = new List<MyCommand>();
public List<MyCommand> Commands
{
get { return _commands; }
}
private void LoadCommands()
{
MyCommand c1 = new MyCommand { Command = GoCommand, Parameter = "1", Text = "Menu1", Checked = true};
MyCommand c2 = new MyCommand { Command = GoCommand, Parameter = "2", Text = "Menu2", Checked = true };
MyCommand c3 = new MyCommand { Command = GoCommand, Parameter = "3", Text = "Menu3", Checked = false };
MyCommand c4 = new MyCommand { Command = GoCommand, Parameter = "4", Text = "Menu4", Checked = true };
MyCommand c5 = new MyCommand { Command = GoCommand, Parameter = "5", Text = "Menu5", Checked = false };
_commands.Add(c1);
_commands.Add(c2);
_commands.Add(c3);
_commands.Add(c4);
_commands.Add(c5);
}
public ICommand GoCommand { get; private set; }
private void OnGoCommand(object obj)
{
}
private bool CanGoCommand(object obj)
{
return true;
}
}
这是保存命令的类:
public class MyCommand
{
public ICommand Command { get; set; }
public string Text { get; set; }
public string Parameter { get; set; }
public Boolean Checked { get; set; }
}
关于c# - 绑定(bind) MenuItem 的 ItemsSource 和 IsChecked 以获取 WPF 中的可检查项列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3113967/