【问题标题】:How to execute command on button in WPF?如何在 WPF 中的按钮上执行命令?
【发布时间】: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 中做了一个断点,发现它们没有被调用。
  • 我没有将参数应用到我的方法中,因为,好吧,我认为我在使用参数进行操作时可能犯了一个错误,所以我决定尝试“干净”版本进行测试.

标签: c# wpf mvvm


【解决方案1】:

您的按钮需要进行不同的绑定,因为在列表模板内部您无法访问全局 DataContext 只能访问本地。您需要使用相对源来访问全局 DataContext。

Command="{Binding Path=DataContext.AddNewTimesheetEntryCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2017-12-23
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多