我在datagrid的第一列有按钮。我正在使用MVVM并尝试在ViewModel中将Command绑定到Command,但是当我单击每行中的按钮时,它不起作用(它不会在ViewModel中调用Command)但是如果我将该按钮移出datagrid则它正常工作。
如何从MVVM中的datagrid中的按钮触发事件?
更新1:
XAML的代码是:
<datagrid:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center">
<Button x:Name="button" Content="View" Margin="5" DataContext="{StaticResource XDataContext}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ViewOrganizationCommand}"
CommandParameter="{Binding ElementName=dtgOrganizations, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
</DataTemplate>
</datagrid:DataGridTemplateColumn.CellTemplate>
ViewModel的代码是:
public ViewModelCommand ViewOrganizationCommand { get; set; }
答案 0 :(得分:1)
为什么不直接绑定到Button.Command而不是使用EventTrigger呢?
<Button
...other properties...
Command="{Binding ViewOrganizationsCommand}"
CommandParameter="{Binding}"/>
这将绑定命令,并将CommandParameter设置为Button的DataContext,这可能是将参数绑定到的好东西。如果不是,只需将CommandParameter绑定到其他可帮助您唯一标识所单击的特定行的其他内容。
答案 1 :(得分:1)
This article带来了DataContextProxy的解决方案。应用此解决方案可以编写像Austin Lamb的答案一样的按钮代码。
答案 2 :(得分:0)
使用事件触发器的命令绑定看起来很好(这是我总是这样做的), 但我怀疑你的命令从未分配给(你正在使用自动属性) 我通常这样做:
private ViewModelCommand viewOrganizationCommand;
public ViewModelCommand ViewOrganizationCommand
{
get
{
if (viewOrganizationCommand == null)
viewOrganizationCommand = new ViewModelCommand(Action, CanDoIt);
return viewOrganizationCommand;
}
}
答案 3 :(得分:0)
尝试将Button
的DataContext设置为StackPanel并设置Button的Command和CommandParameter。
<datagrid:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center" DataContext="{StaticResource XDataContext}">
<Button x:Name="button" Content="View" Margin="5" Command="{Binding ViewOrganizationCommand}" CommandParameter="{Binding ElementName=dtgOrganizations, Path=SelectedItem}" >
</Button>
</StackPanel>
</DataTemplate>
</datagrid:DataGridTemplateColumn.CellTemplate>
答案 4 :(得分:0)
DataGrid的每一行都将其DataContext设置为该对象。如果网格的ItemSource是ObservableCollection,则每一行的DataContext都是Organization对象。
有两种方法可以解决这个问题。
创建一个公开命令的包装或扩展ViewModel。然后该命令应该触发。这是一些伪代码。
public class OrganizationExtensionViewModel
{
<summary>
/// Private currentOrginization property.
/// </summary>
private Organization currentOrginization;
public Organization CurrentOrganization
{
get
{
return this.currentOrginization;
}
set
{
if (this.currentOrginization != value)
{
this.currentOrginization = value;
this.RaisePropertyChanged("CurrentOrganization");
}
}
}
public ViewModelCommand ViewOrganizationCommand { get; set; }
public OrganizationExtensionViewModel(Organization o)
{
this.CurrentOrganization = o;
this.ViewOrganizationCommand = new ViewModelCommand(this.ViewOrgnaizationClicked);
}
}
将xaml中的ViewModel定义为StaticResource,并将其称为绑定路径。
... 在网格中
<Button x:Name="button" Content="View" Margin="5" Command="{Binding ViewOrganizationCommand, Source={StaticResource viewModel}}" />
答案 5 :(得分:0)
我通过使用MVVMLight Toolkit
中的EventToCommand行为解决了这个问题