按钮上的绑定命令不起作用wpf mvvm

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按钮上的绑定命令不起作用wpf mvvm相关的知识,希望对你有一定的参考价值。

我正在尝试创建简单的添加实体到数据库表单,但绑定命令不起作用,我无法弄清楚为什么。这是XAML

<DockPanel Margin="30">
    <StackPanel DockPanel.Dock="Top">
        <Label>Manufacturer</Label>
        <TextBox Text="{Binding Manufacturer, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
        <Label>Type</Label>
        <TextBox Text="{Binding Type, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
        <Label>Serial number</Label>
        <TextBox Text="{Binding SerialNumber, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
        <Button Command="{Binding AddScaleCommand}">Add Scale</Button>
    </StackPanel>
    <ListBox ItemsSource="{Binding Scales}" DockPanel.Dock="Bottom"></ListBox>
</DockPanel>

这里是命令所在的ScaleViewModel

public class ScaleViewModel : ViewModel
{
    public ScaleViewModel()
    {
        Scales = new ObservableCollection<Scale>();
    }

    public ICollection<Scale> Scales { get; private set; }
    public string Manufacturer { get; set; }
    public string Type { get; set; }

    public string SerialNumber { get; set; }

    public bool IsValid
    {
        get
        {
            return !string.IsNullOrWhiteSpace(SerialNumber);
        }
    }

    public ActionCommand AddScaleCommand
    {
        get
        {
            return new ActionCommand(p => AddScale(Manufacturer, Type, SerialNumber), 
                                    p => IsValid);
        }
    }

    private void AddScale(string manufacturer, string type, string serialNumber)
    {
        using (var api = new BusinessContext())
        {
            var scale = new Scale
            {
                Manifacturer = manufacturer,
                Type = type,
                SerialNumber = serialNumber
            };
            try
            {
                api.AddNewScale(scale);
            }
            catch (Exception ex)
            {
                //TODO kasnije
                return;
            }

            Scales.Add(scale);
        };
    }
}

Scale是简单类,具有3个属性(制造商,类型和序列号),ViewModel类实现INotifyPropertyChanged和IDataErrorInfo并实现必要的方法。 ActionCommand类实现ICommand并实现ICommand方法。

UPDATE添加了ActionCommand类

public class ActionCommand : ICommand
{
    private readonly Action<Object> action;
    private readonly Predicate<Object> predicate;

    public ActionCommand(Action<Object> action) : this(action, null)
    {

    }

    public ActionCommand(Action<Object> action, Predicate<Object> predicate)
    {
        if (action == null)
        {
            throw new ArgumentNullException("Action", "Yout must specify an Action<T>");
        }

        this.action = action;
        this.predicate = predicate;
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        if (predicate == null)
        {
            return true;
        }

        return predicate(parameter);
    }

    public void Execute(object parameter)
    {
        action(parameter);
    }

    public void Execute()
    {
        Execute(null);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    #endregion
}
答案

您的ViewModel类需要实现IDataErrorInfo和INotifyPropertyChanged才能使验证生效。

此外,在SerialNumber发生更改后,ActionCommand没有任何方法可以重新评估IsValid()。

有关使用IDataErrorInfo在WPF / MVVM中进行数据验证的更多详细信息,请查看我的blog post

另一答案

问题是我没有在App.xaml.cs中将DataContext添加到MainWindow

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var window = new MainWindow
        {
            DataContext = new ScaleViewModel()
        };

        window.ShowDialog();
    }
}

以上是关于按钮上的绑定命令不起作用wpf mvvm的主要内容,如果未能解决你的问题,请参考以下文章

命令绑定在带有棱镜的 WPF 中不起作用

2019-11-29-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因...

WPF:如何使用 MVVM 将命令绑定到 ListBoxItem?

ItemsControl 上的 WPF MVVM 单选按钮

wpf MVVM框架基础

WPF 中的选择性双命令绑定转换器?