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

时间:2018-12-19 15:25:06

标签: c# 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
}

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

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

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

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

        window.ShowDialog();
    }
}