【发布时间】:2019-06-30 02:56:45
【问题描述】:
我需要在每个ListViewItem 中有一个按钮。我在DataTemplate 中创建了Button,绑定了命令,当我按下按钮时它没有被执行。它只是没有被调用。
我指的是不同的教程和问题,例如
WPF Button doesn't execute Command 或 How to bind WPF button to a command in ViewModelBase? 并创建了一个 RelayCommand 类,该类实现了 ICommand。
实际上,我需要使用参数来调用动作,但是没有参数我什至无法让它工作,所以我打算接下来开始使用它。其他一切都完美绑定,就像一个魅力。
查看
<Page.Resources>
<CollectionViewSource x:Key='src'
Source="{Binding TimesheetEntries}"
>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Date" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Page.Resources>
<Page.DataContext>
<ViewModels:TimesheetViewModel/>
</Page.DataContext>
<ListView
x:Name="TimesheetEntriesListView"
Margin="10"
Grid.Row="1"
Grid.ColumnSpan="2"
ItemsSource="{Binding Source={StaticResource src}}"
SelectedItem="{Binding SelectedEntry, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="30" Margin="3" IsEnabled="{Binding IsEditable}">
<ComboBox
SelectedValuePath="Key" DisplayMemberPath="Value"
ItemsSource="{Binding EmploymentTypesDictionary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedEmployment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="300"/>
<TextBox
Text="{Binding Hours, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat=N2}"
Margin="5,0,0,0"
Height="Auto"
IsEnabled="{Binding HoursAvaliable}"
Width="70"/>
<Button Margin="5,0,10,0"
Content="+"
Command="{Binding AddNewTimesheetEntryCommand}"
CommandParameter="{Binding Path=Name}"
></Button>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Margin="5,5,5,0" Orientation="Horizontal">
<TextBlock FontSize="14" Text="{Binding Path=Name, StringFormat='{}{0:dd/MM/yyyy, dddd}'}"/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
视图模型
class TimesheetViewModel : BaseViewModel
{
public ICommand AddNewTimesheetEntryCommand
{
get
{
return _AddNewTimesheetEntryCommand ?? new RelayCommand(AddNewTimesheetEntry);
}
}
private ICommand _AddNewTimesheetEntryCommand;
public void AddNewTimesheetEntry(object parameter)
{
//Do stuff
}
public TimesheetViewModel()
{
}
}
中继命令
public class RelayCommand : ICommand
{
private Action<object> mAction;
public event EventHandler CanExecuteChanged = (sender, e) => { };
public RelayCommand(Action<object> action)
{
mAction = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
mAction(parameter);
}
}
【问题讨论】:
-
首先,为什么你的命令有一个 setter ?你有没有改变过命令?您可以将其更改为
public ICommand AddNewTimesheetEntryCommand {get;},并且只在构造函数中设置一次,例如AddNewTimesheetEntryCommand = new RelayCommand(AddNewTimesheetEntry)。说的时候。您是如何确定它不起作用的? -
而且 RelayCommand.Execute 方法还有一个对象参数,为什么不应用到您的 AddNewTimesheetEntry ?
-
我在所需的方法和 RelayCommand.Execute 中做了一个断点,发现它们没有被调用。
-
我没有将参数应用到我的方法中,因为,好吧,我认为我在使用参数进行操作时可能犯了一个错误,所以我决定尝试“干净”版本进行测试.