简体   繁体   English

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

[英]Binding command on button doesn't work wpf mvvm

I'm trying to create simple add entity to database form, but binding command doesn't work and I can't figure out why. 我正在尝试向数据库表单创建简单的添加实体,但是绑定命令不起作用,我不知道为什么。 Here is XAML 这是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>

And here is ScaleViewModel where the command is located 这是命令所在的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 is simple class with 3 properties (Manufacturer, type and serial number), and ViewModel class implements INotifyPropertyChanged and IDataErrorInfo and implemented necessary methods. Scale是具有3个属性(制造商,类型和序列号)的简单类,ViewModel类实现INotifyPropertyChanged和IDataErrorInfo并实现必需的方法。 ActionCommand class implements ICommand and implements ICommand methods. ActionCommand类实现ICommand并实现ICommand方法。

UPDATE added ActionCommand class 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
}

Your ViewModel class needs to implement both IDataErrorInfo and INotifyPropertyChanged for the validation to work. 您的ViewModel类需要实现IDataErrorInfo和INotifyPropertyChanged才能使验证生效

Also, there doesn't appear any way for the ActionCommand to re-evaluate IsValid() after SerialNumber has changed. 此外,在更改SerialNumber后,ActionCommand似乎没有任何方法可以重新评估IsValid()。

For more detail on data validation in WPF / MVVM using IDataErrorInfo, check out my blog post . 有关使用IDataErrorInfo在WPF / MVVM中进行数据验证的更多详细信息,请参阅我的博客文章

The problem was I didn't add DataContext to MainWindow in App.xaml.cs 问题是我没有在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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM