更新
我试图使用的按钮位于<DataTemplate>
内,这显然导致了问题。一旦我在<ItemsControl>
区域外的按钮上尝试了代码,它就能正常工作。任何人都可以告诉我,为什么它不能用于<ItemsControl>
和<DataTemplate>
这样的重复按钮?
我正在尝试基于TutorialsPoints.com的文章实现MVVM通信模式。我稍微修改了代码,但总的来说它仍然非常类似于文章中的代码。我想要做的是,一旦点击一个按钮就在控制台中写一行。
通过我的实现(参见下面的代码),单击按钮时没有任何反应。我还尝试在OnClick()
函数中添加一个断点来查看是否运行了,但事实并非如此。但是MyICommand()
的构造函数中的断点表明该类实际上已初始化。那我做错了什么?
按钮
<Button Content="Do stuff!"
Command="{Binding FakeCommand}"
Cursor="Hand"
Background="Red"
Foreground="White"
BorderThickness="0"
Padding="10 0 10 0" />
视图模型
public class AgreementViewModel : INotifyPropertyChanged
{
public MyICommand FakeCommand { get; set; }
public AgreementViewModel ()
{
LoadAgreements();
FakeCommand = new MyICommand(OnClick, CanClick);
FakeCommand.RaiseCanExecuteChanged();
}
private void OnClick()
{
Console.WriteLine("Something was clicked...");
}
private bool CanClick()
{
return true;
}
}
ICommand的实施
public class MyICommand : ICommand
{
Action _TargetExecuteMethod;
Func<bool> _TargetCanExecuteMethod;
public event EventHandler CanExecuteChanged = delegate {};
public MyICommand(Action executeMethod)
{
_TargetExecuteMethod = executeMethod;
}
public MyICommand(Action executeMethod, Func<bool> canExecuteMethod)
{
_TargetExecuteMethod = executeMethod;
_TargetCanExecuteMethod = canExecuteMethod;
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
bool ICommand.CanExecute(object parameter)
{
if (_TargetCanExecuteMethod != null)
{
return _TargetCanExecuteMethod();
}
if (_TargetExecuteMethod != null)
{
return true;
}
return false;
}
void ICommand.Execute(object parameter)
{
_TargetExecuteMethod?.Invoke();
}
}
答案 0 :(得分:2)
如果您有ItemsControl
(正如您在更新版本中提到的那样),那么DataContext
的每个实例化的DataTemplate
将ItemsSource
中的每个项目使用ElementName
1}}。要绑定到父视图模型中的命令,可以使用 <ItemsControl ItemsSource="{Binding Data}" x:Name="root">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="Do stuff!"
Command="{Binding DataContext.FakeCommand, ElementName=root}"
Cursor="Hand"
Background="Red"
Foreground="White"
BorderThickness="0"
Padding="10 0 10 0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
来获取ItemsControl
RelativeSource
如果您不想使用名称,另一种方法是使用Command="{Binding DataContext.FakeCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
来获取项目控件:
ItemsControl
请注意,在这两种情况下,数据上下文都是DataContext.FakeCommand
,因此您需要执行DataContext
,ItemsControl
这里指的是CommandParameter={Binding}
的数据上下文
您可能还需要调用该命令的项,因为可以为源集合中的任何项调用它。要做到这一点,你可以添加一个o < develop
|
o < staging
|
o < v0.2
|
o < v0.1
,传递命令的参数将是项目(你的实现不会将参数传递给委托,但它可以)
答案 1 :(得分:-2)
从 CanExecute 和执行方法移除ICommand.
。