解决 MVC模式的问题-带按钮的ICommand

madaxe2020

成员
已加入
2020年9月7日
留言内容
17
编程经验
5-10
我希望有人可以提供帮助,我正在学习M-V-VM模式,在此示例中,当文本字段中没有任何字符串并且选择了按钮时,该按钮应被抛出调试断言,该按钮应被停用。

没有错误,警告它只是行不通,该按钮似乎与视图模型分离,我不知道为什么

谢谢

马达克斯


Model:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;

namespace MVVM_Learning.Models
{
    public class CustomerModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _Name;
        public string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
                NotifyPropertyChanged("Name");
            }
        }
        public CustomerModel(string CustomerName)
        {
            this.Name = CustomerName;
        }


        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
View Model:
using MVVM_Learning.Commands;
using MVVM_Learning.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Input;

namespace MVVM_Learning.ViewModels
{
    public class CustomerViewModel
    {
        public ICommand UpdateCommand { get; private set; }
        public CustomerModel customerModel {get; private set; }
        public bool CanUpdate
        {
            get
            {
                if(this.customerModel == null)
                {
                    return false;
                }
                return !String.IsNullOrWhiteSpace(this.customerModel.Name);
            }
        }
        public CustomerViewModel()
        {
            // Normally Get From Database
            this.customerModel = new CustomerModel("Bob");
            this.UpdateCommand = new CustomerUpdateCommand(this);
        }
        public void SaveChanges()
        {
            // Normally Save to Database
            Debug.Assert(false, String.Format("{0} Was Updated.", this.customerModel.Name));
        }
    }
}

View:
using MVVM_Learning.ViewModels;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace MVVM_Learning.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new CustomerViewModel();
        }
    }
}

Command:
using MVVM_Learning.ViewModels;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;

namespace MVVM_Learning.Commands
{
    internal class CustomerUpdateCommand : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        private CustomerViewModel _customerViewModel;
        public CustomerUpdateCommand(CustomerViewModel cusomerViewModel)
        {
            this._customerViewModel = cusomerViewModel;
        }

        public bool CanExecute(object parameter)
        {
            return this._customerViewModel.CanUpdate;
        }

        public void Execute(object parameter)
        {
            this._customerViewModel.SaveChanges();
        }
    }
}
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,933
地点
英国
编程经验
10+
NotifyPropertyChanged("Name");
不需要按原样指定。
以下面的伪代码为例:
C#:
        public string LastLoginAt
        {
            get => lastLoginAt;
            set { lastLoginAt = value; OnPropertyChanged(); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string new_Value = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(new_Value));
        }
OnPropertyChanged -通过引发事件知道调用代码是什么。

在您的情况下,您要在第10行中指定不需要的位置:
C#:
        public string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
                NotifyPropertyChanged("Name");
            }
        }
值得指出的是,它并不能解决您的问题。这就是为什么我们使用调试器。从应用程序启动的那一刻起,您还必须使用调试器并进入代码,并确定类似的异常情况。您可以在我的签名中找到Microsoft的调试教程。

还有一件事,这是错误的:
C#:
namespace MVVM_Learning.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new CustomerViewModel();
        }
    }
}
应该 :
C#:
namespace MVVM_Learning.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {    
        public readonly CustomerViewModel CVM = new CustomerViewModel();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = CVM;
        }
    }
}
在课程级别上声明您的模型。如果在方法级别声明新对象,它们将仅在该方法的生命周期中存在。并且对该新对象的任何调用都将要求您调用一个新实例,否则您将发现您的模型也可能为null。我多年来一直使用相同的M-V-V-M,这对我来说很有效。我也建议您阅读有关致电 新的 关键词。 新修饰符-C#参考.
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,933
地点
英国
编程经验
10+
还有其他一些小问题可以调整,我没有时间去研究。对不起。但是也许其他人会看看我没有回应的其他一些内容。

我真正认为对您更有用的是,开始使用调试器,并查看代码在执行时的工作,如果发现更多不正常的行为,则可以在此处询问为什么它在特定的行为方式,其他人会为您代收。很高兴为您提供帮助。
 
最佳 底部