我有一个自定义的SplitButton实现,其中包含一个ComboBox,其中包含几个绑定到命令的ComboBoxItem。我可以绑定到命令的Name和Text属性,但无法将ComboBoxItem的 IsEnabled 属性绑定到Command的 CanExecute 方法的结果,因为它是一个方法。是否有一些我不知道绑定到方法的语法,或者是否有一些技巧可以帮助我绑定到CanExecute。
顺便说一下,我已经考虑过使用自定义的ValueConverter,除了我意识到在重新评估CanExecute时我可能不会收到任何更新,因为它不是属性,因为我的命令不是业务对象。它在我看来,我可能必须为命令创建一个ViewModel,以便仅在我的自定义SplitButton控件中使用,但这对我来说似乎有些过分。
答案 0 :(得分:1)
你可以在ItemContainerStyle(ComboBoxItem样式)中放一个按钮(如果你没有一个绑定到ICommand的controltemplate中),并将命令绑定到它 并添加一个Trigger来检查Button.IsEnabled并将该值设置为ComboBoxItem。所以这里我们使用Button作为CommandSource来从CanExeute获取IsEnabled。您可以将按钮的高度和宽度设置为零
<ControlTemplate....>
<Grid ...
<Button x:Name="dummyButton" Command="{Binding YourCommand}" ....
......
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="dummyButton" Property="IsEnabled" Value="False">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</ControlTemplate.Triggers>
答案 1 :(得分:1)
ViewModel的另一个解决方案。以下是我使用ViewModel解决问题的方法。请注意,漂亮的NotifyPropertyChanged方法是我的基本ViewModel类的一部分。
public class RoutedUICommandViewModel : ViewModel
{
private RoutedUICommand _command;
private IInputElement _target;
public string Name { get { return _command.Name; } }
public string Text { get { return _command.Text; } }
public bool CanExecute
{
get
{
return _command.CanExecute(null, _target);
}
}
public RoutedUICommand Command { get { return _command; } }
public RoutedUICommandViewModel(ReportCommand command, IInputElement target)
{
_command = command;
_target = target;
_command.CanExecuteChanged += _command_CanExecuteChanged;
}
private void _command_CanExecuteChanged(object sender, EventArgs e)
{
base.NotifyPropertyChanged(() => this.CanExecute);
}
}
答案 2 :(得分:1)
我在MSDN论坛上找到了this discussion,其中Dr. WPF建议使用attached behavior来解决这个问题。他举了下面的例子,说明如何使用它。
<Grid behaviors:CommandBehaviors.EnablingCommand="{x:Static commands:testcommand.test}">
. . .
</Grid>
虽然这个解决方案看起来很不错,但我还是没有时间去理解这种行为将如何实现以及涉及到什么。如果有人想详细说明请另外做,如果我有机会探索这个选项,我会更详细地修改这个答案。
答案 3 :(得分:0)
我在代码中解决此问题的方法是在ComboBox上为PreviewMouseDown事件添加事件处理程序。这是处理程序:
private void comboBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
ViewModel vm = this.DataContext as ViewModel;
if (vm != null)
{
if (!vm.CanChangeSelection())
{
e.Handled = true;
vm.RespondToFailedAttemptChangeUnits();
}
}
}
在我只需要在一个位置执行此操作的情况下,这对我很有用。如果我有很多像这样的页面,它可能会有点小调。
另外,虽然我遵循MVVM模式,但我不是纯粹主义者 - 我认为这是一个很好的实用解决方案,遵循MVVM的精神,如果不是字母。