WPF 按钮命令未在 ViewModel 中触发 ICommand
WPF Button Command not firing ICommand in ViewModel
我有一个带有按钮的视图,如下所示:
<Button Grid.Column="2" Grid.Row="1" Content="Test" Margin="10,4"
Command="{Binding DataContext.CmdTestButtonClicked}"
CommandParameter="{Binding}" />
在视图的代码隐藏中,我将 DataContext 设置为 ViewModel:
public GlobalSettings()
{
InitializeComponent();
...
DataContext = Helpers.IoCHelper.GlobalSettingsVM;
...
}
我的 ViewModel 派生自基础 class,它暴露了 ICommand
:
public class GlobalSettingsVM : CollectionViewModel<GlobalSettings> { ... }
public abstract class CollectionViewModel<TModel> : IInstallModuleViewModel, INotifyPropertyChanged,
INotifyDataErrorInfo where TModel : Model, new()
{
...
public ICommand CmdTestButtonClicked
{
get
{
return _testButtonClicked ??
(_testButtonClicked = new RelayCommand(TestButtonClicked));
}
}
protected virtual void TestButtonClicked(object o)
{
// I never get here
}
}
我在整个应用程序中使用此模式没有任何其他问题,但是我的所有其他实现在 ListView
中都有 Button
,因此我必须使用 RelativeSource={RelativeSource AncestorType={x:Type ListView}}
.
为什么这个命令永远不会触发?我也需要在这里设置一个RelativeSource
吗?
这个
Command="{Binding DataContext.CmdTestButtonClicked}"
暗示该命令将在按钮绑定到的对象中查找名为 DataContext
的 属性。
如果按钮的 DataContext 是 GlobalSettingsVM
这应该有效:
Command="{Binding CmdTestButtonClicked}"
您也可以使用 MVVM Light 工具包,它非常方便,可以帮助解决这些情况。
你会得到这样的东西:
<Button Grid.Column="2" Grid.Row="1" Content="Test" Margin="10,4"
<i:Interaction.Triggers>
<i:EventTrigger EventName="OnClick" >
<Command:EventToCommand Command="{Binding DataContext.CmdTestButtonClicked}" CommandParameter="{Binding}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
在我的例子中,我正在 xaml.cs
class 的构造函数下收听 PreviewMouseLeftButtonDown
正在停止 command event callback
到 view model
.
this.PreviewMouseLeftButtonDown += (s, e) => DragMove();
在 xaml 文件中为 window
添加了 MouseLeftButtonDown="Window_MouseLeftButtonDown"
单击处理程序并处理 window 在其中拖动,而不是上面的行,如下所示
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
我有一个带有按钮的视图,如下所示:
<Button Grid.Column="2" Grid.Row="1" Content="Test" Margin="10,4"
Command="{Binding DataContext.CmdTestButtonClicked}"
CommandParameter="{Binding}" />
在视图的代码隐藏中,我将 DataContext 设置为 ViewModel:
public GlobalSettings()
{
InitializeComponent();
...
DataContext = Helpers.IoCHelper.GlobalSettingsVM;
...
}
我的 ViewModel 派生自基础 class,它暴露了 ICommand
:
public class GlobalSettingsVM : CollectionViewModel<GlobalSettings> { ... }
public abstract class CollectionViewModel<TModel> : IInstallModuleViewModel, INotifyPropertyChanged,
INotifyDataErrorInfo where TModel : Model, new()
{
...
public ICommand CmdTestButtonClicked
{
get
{
return _testButtonClicked ??
(_testButtonClicked = new RelayCommand(TestButtonClicked));
}
}
protected virtual void TestButtonClicked(object o)
{
// I never get here
}
}
我在整个应用程序中使用此模式没有任何其他问题,但是我的所有其他实现在 ListView
中都有 Button
,因此我必须使用 RelativeSource={RelativeSource AncestorType={x:Type ListView}}
.
为什么这个命令永远不会触发?我也需要在这里设置一个RelativeSource
吗?
这个
Command="{Binding DataContext.CmdTestButtonClicked}"
暗示该命令将在按钮绑定到的对象中查找名为 DataContext
的 属性。
如果按钮的 DataContext 是 GlobalSettingsVM
这应该有效:
Command="{Binding CmdTestButtonClicked}"
您也可以使用 MVVM Light 工具包,它非常方便,可以帮助解决这些情况。
你会得到这样的东西:
<Button Grid.Column="2" Grid.Row="1" Content="Test" Margin="10,4"
<i:Interaction.Triggers>
<i:EventTrigger EventName="OnClick" >
<Command:EventToCommand Command="{Binding DataContext.CmdTestButtonClicked}" CommandParameter="{Binding}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
在我的例子中,我正在 xaml.cs
class 的构造函数下收听 PreviewMouseLeftButtonDown
正在停止 command event callback
到 view model
.
this.PreviewMouseLeftButtonDown += (s, e) => DragMove();
在 xaml 文件中为 window
添加了 MouseLeftButtonDown="Window_MouseLeftButtonDown"
单击处理程序并处理 window 在其中拖动,而不是上面的行,如下所示
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}