我写了一个简单的项目,他们的问题是一样的
型号
Persons.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Learn.MVVM.Example.Annotations;
namespace Learn.MVVM.Example.Models.Business
{
public class Person : INotifyPropertyChanged
{
#region Fields
private string _firstName;
private string _middleName;
private string _lastName;
private DateTime _dateOfBirth;
private Gender _gender;
#endregion Fields
#region Properties
public string FirstName
{
get { return _firstName; }
set
{
if (value == _firstName) return;
_firstName = value;
OnPropertyChanged();
}
}
public string MiddleName
{
get { return _middleName; }
set
{
if (value == _middleName) return;
_middleName = value;
OnPropertyChanged();
}
}
public string LastName
{
get { return _lastName; }
set
{
if (value == _lastName) return;
_lastName = value;
OnPropertyChanged();
}
}
public DateTime DateOfBirth
{
get { return _dateOfBirth; }
set
{
if (value.Equals(_dateOfBirth)) return;
_dateOfBirth = value;
OnPropertyChanged();
}
}
public Gender Gender
{
get { return _gender; }
set
{
if (value == _gender) return;
_gender = value;
OnPropertyChanged();
}
}
#endregion Properties
#region Constructors
public Person()
{
}
public Person(string firstName, string middleName, string lastName, DateTime dateOfBirth, Gender gender)
{
FirstName = firstName;
MiddleName = middleName;
LastName = lastName;
DateOfBirth = dateOfBirth;
Gender = gender;
}
#endregion Constructors
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
//[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion INotifyPropertyChanged
}
public enum Gender
{
Male,
Female
}
}
人物模型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Learn.MVVM.Example.Models.Business;
namespace Learn.MVVM.Example.Models
{
public class PersonModel
{
#region Constructors
public PersonModel()
{
}
#endregion Constructors)
#region Methods
public List<Person> GetPersons()
{
return new List<Person>
{
new Person("Алексей", "Алексеевич", "Алексеев", new DateTime(1980, 5, 10), Gender.Male),
new Person("Петр", "Петрович", "Петров", new DateTime(1977, 9, 21), Gender.Male),
new Person("Виктория", "Викторовна", "Викторова", new DateTime(1991, 1, 7), Gender.Female)
};
}
#endregion Methods
}
}
视图模型
IViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Learn.MVVM.Example.ViewModels
{
public interface IViewModel
{
}
}
PersonsViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Learn.MVVM.Example.Common.Commands;
using Learn.MVVM.Example.Models;
using Learn.MVVM.Example.Models.Business;
using Learn.MVVM.Example.Views;
namespace Learn.MVVM.Example.ViewModels
{
public class PersonsViewModel<TViewType> : IViewModel where TViewType : IView, new()
{
private readonly IView _view;
private readonly PersonModel _model;
public ObservableCollection<Person> Persons { get; set; }
public RelayCommand OkCommand { get; private set; }
private string _str;
public PersonsViewModel()
{
this._view = new TViewType();
this._model = new PersonModel();
this.Persons = new ObservableCollection<Person>(this._model.GetPersons());
this.OkCommand = new RelayCommand(o => this.OKRun());
_str = "Кнопка";
this._view.SetDataContext(this);
this._view.ShowView();
}
public string Str
{
get { return _str; }
set
{
if (_str == value)
return;
_str = value;
OnPropertyChanged("Str");
}
}
public event PropertyChangedEventHandler PropertyChanged;
//[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private void OKRun()
{
_str = "Change";
}
}
}
查看
IView.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Learn.MVVM.Example.Views
{
public interface IView
{
void ShowView();
void ShowViewAsModal();
void SetDataContext(object dataContext);
}
}
PersonsView.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 Learn.MVVM.Example.Views
{
/// <summary>
/// Логика взаимодействия для PersonsView.xaml
/// </summary>
public partial class PersonsView: IView
{
public PersonsView()
{
InitializeComponent();
}
public void ShowView()
{
this.Show();
}
public void ShowViewAsModal()
{
this.ShowDialog();
}
public void SetDataContext(object dataContext)
{
this.DataContext = dataContext;
}
}
}
PersonsView.xaml
<Window x:Class="Learn.MVVM.Example.Views.PersonsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PersonsView" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{Binding Persons}" />
<Button Content="{Binding Str, UpdateSourceTrigger=PropertyChanged}" DataContext="{Binding Str}" Name="OKButton" Command="{Binding OkCommand}" Grid.Row="1"/>
</Grid>
</Window>
命令
RelayCommands.cs
using System;
using System.Windows.Input;
namespace Learn.MVVM.Example.Common.Commands
{
public class RelayCommand : ICommand
{
private Predicate<object> canExecute;
private Action<object> execute;
public RelayCommand(Action<object> execute) : this(execute, DefaultCanExecute)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
if (canExecute == null)
{
throw new ArgumentNullException("canExecute");
}
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
CanExecuteChangedInternal -= value;
}
}
public bool CanExecute(object parameter)
{
return canExecute != null && canExecute(parameter);
}
public void Execute(object parameter)
{
execute(parameter);
}
private event EventHandler CanExecuteChangedInternal;
public void OnCanExecuteChanged()
{
var handler = CanExecuteChangedInternal;
if (handler != null)
{
handler.Invoke(this, EventArgs.Empty);
}
}
public void Destroy()
{
canExecute = _ => false;
execute = _ => { };
}
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
}