【发布时间】:2018-06-18 12:22:23
【问题描述】:
更新
我尝试使用的按钮位于 <DataTemplate> 内,这显然是导致问题的原因。一旦我在<ItemsControl> 区域外的按钮上尝试了代码,它就可以工作了。谁能告诉我,为什么它在 <ItemsControl> 和 <DataTemplate> 这样的重复按钮中不起作用?
我正在尝试实现一种 MVVM 通信模式,基于 TutorialsPoints.com 的一篇文章。我稍微修改了代码,但总的来说它仍然与文章中的代码非常相似。我想要做的是,单击按钮后在控制台中写一行。
在我的实现中(参见下面的代码),当我单击按钮时没有任何反应。我还尝试在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();
}
}
【问题讨论】:
-
你将 ViewModel 绑定到 View 吗?通过设置视图的
DataContext? -
@Noceo 您希望在哪里看到您的消息?如果将这一行写入文件,它会起作用吗?
-
改用
Debug.WriteLine,或者只是设置一个断点。我还建议编写CanExecuteChanged?.Invoke(this, EventArgs.Empty);并摆脱delegate {}初始化。 -
听起来更像是
ItemsControl引起的,它会为每个项目引入一个新的DataContext。 -
这个stackoverflow.com/questions/3404707/… 是对神奇的谷歌搜索“WPF ItemsControl Binding Parent”的回答;)请注意链接的问题可能令人困惑,但接受的答案很清楚