我有类似下面的内容。对于MenuItem
,我在这里将MenuItem
的对象作为CommandParameter
传递。这对我来说很好。我的MenuItem
拥有RadioButton
,我想对此CommandParameter
使用MenuItem RadioButton
值。谁能帮助我如何做到这一点。在此先感谢。
<MenuItem Header="Name"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Command="{Binding SortCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}">
<MenuItem.Icon>
<RadioButton VerticalAlignment="Center"
Margin="3"
IsChecked="True"
GroupName="sort"
Command="{Binding SortCommand}"
CommandParameter="..." />
</MenuItem.Icon>
</MenuItem>
现在Command
仅在我选择MenuItem
时才会执行。我想在用户同时选择RadioButton
时也这样做。以下是我正在使用的代码。
public void OnSortCommandExecuted(object menuItem)
{
MenuItem menu = menuItem as MenuItem;
if (menu != null)
{
((RadioButton)menu.Icon).IsChecked = !((RadioButton)menu.Icon).IsChecked;
this.eAggregator.GetEvent<ImagesSortedEvent>().Publish(menu.Header.ToString());
}
}
答案 0 :(得分:1)
就像我在评论中所说的那样,将UI组件作为CommandParameter
传递给ViewModel并不是一个好习惯,因为ViewModel不应该知道View。
我建议你在ViewModel中使用正确的绑定。 在ViewModel中创建一个bool
属性,并与radioButton的IsChecked
DP绑定。这样您就不必从View中传递任何CommandParameter
,只需从命令执行方法中检查bool属性的状态。
现在,为什么无法从RadioButton访问
MenuItem
?
RadioButton 与MenuItem不在同一个Visual树中。
因此,您无法使用RelativeSource
前往MenuItem。另外ElementName
绑定在这里不起作用,因为这两个元素应该位于同一个Visual Tree中。
在这种情况下,你可能会发现over net使用x:Reference
,其中两个元素不在同一个Visual树中但在这里不起作用,因为它会产生循环依赖。
最后,您必须使用它来使用Freezable
类对象来保存MenuItem的实例并在绑定中使用该资源。
首先您需要定义派生自Freezable
的类:
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy));
}
你可以在XAML中使用它来传递MenuItem:
<MenuItem Header="Name"
x:Name="menuItem"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Command="{Binding SortCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}">
<MenuItem.Resources>
<local:BindingProxy x:Key="proxy"
Data="{Binding Source={x:Reference menuItem}}"/>
</MenuItem.Resources>
<MenuItem.Icon>
<RadioButton VerticalAlignment="Center"
Margin="3"
IsChecked="True"
GroupName="sort"
Command="{Binding SortCommand}"
CommandParameter="{Binding Data.CommandParameter,
Source={StaticResource proxy}}"/>
</MenuItem.Icon>
</MenuItem>
当然,您需要在XAML中声明local
命名空间。
PS - 我仍然坚持使用第一种方法在ViewModel中定义正确的绑定。
<强>更新强>
如果MenuItem
位于ContextMenu
下,则无法RelativeSource
绑定。上述方法适用于该情况。
但是如果您将MenuItem直接作为某个控件(如Menu)的子项放置,RelativeSource
绑定将起作用:
CommandParameter="{Binding CommandParameter,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}}"