下面是我解决这个问题的方法。
导入的命名空间
using System;
using System.Windows.Input;
using System.Threading.Tasks;
using ReactiveUI; // nuget package reactiveui
模型
namespace Models
{
public class Station
{
public Station(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("message", nameof(name));
}
Name = name;
}
public string Name { get; }
}
}
服务
namespace Services
{
public interface IStationService
{
Task CreateAsync(Models.Station model);
Task UpdateAsync(Models.Station oldModel, Models.Station newModel);
}
}
ViewModels基地
namespace ViewModels.Base
{
public class ViewModelBase : ReactiveObject
{
public virtual Task InitializeAsync(object parameter)
{
return Task.CompletedTask;
}
}
}
视图模型
如果
Name
为空或等于中的名称
_originalModel
以防止在执行save命令时出现异常。
或者你可以在
SaveCommandExecuteAsync
.
要点是:我只在想保存新模型实例时创建它。
namespace ViewModels
{
public class StationEditViewModel : Base.ViewModelBase
{
public StationEditViewModel(Services.IStationService stationService)
{
StationService = stationService ?? throw new ArgumentNullException(nameof(stationService));
}
protected Services.IStationService StationService { get; }
string _name;
public string Name { get => _name; set => this.RaiseAndSetIfChanged(ref _name, value); }
public ICommand SaveCommand => ReactiveCommand.CreateFromTask(SaveCommandExecuteAsync);
private async Task SaveCommandExecuteAsync()
{
var oldModel = _originalModel;
var newModel = await SaveToModelAsync();
if (oldModel == null)
await StationService.CreateAsync(newModel);
else
await StationService.UpdateAsync(oldModel, newModel);
await LoadFromModelAsync(newModel);
}
public override Task InitializeAsync(object parameter)
{
return LoadFromModelAsync(parameter as Models.Station);
}
Models.Station _originalModel;
private Task LoadFromModelAsync(Models.Station model)
{
_originalModel = model;
Name = model?.Name;
return Task.CompletedTask;
}
private Task<Models.Station> SaveToModelAsync()
{
var model = new Models.Station(Name);
return Task.FromResult(model);
}
}
}
控制台应用程序中的最终测试
namespace so53567553
{
using Models;
class Program
{
static async Task Main(string[] args)
{
var service = new TestStationService();
var vm = new ViewModels.StationEditViewModel(service);
vm.PropertyChanged += (s, e) => Console.WriteLine($"PropertyChanged '{e.PropertyName}'");
// we will work on a new Station
Console.WriteLine("* Create Station");
await vm.InitializeAsync(null);
vm.Name = "New Station";
vm.SaveCommand.Execute(null);
// we will work on an existing Station
Console.WriteLine("* Edit Station");
await vm.InitializeAsync(new Station("Paddington"));
vm.Name = "London";
vm.SaveCommand.Execute(null);
}
}
class TestStationService : Services.IStationService
{
public Task CreateAsync(Station model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
Console.WriteLine($"Create Station '{model.Name}'");
return Task.CompletedTask;
}
public Task UpdateAsync(Station oldModel, Station newModel)
{
if (oldModel == null)
{
throw new ArgumentNullException(nameof(oldModel));
}
if (newModel == null)
{
throw new ArgumentNullException(nameof(newModel));
}
Console.WriteLine($"Update Station from '{oldModel.Name}' to '{newModel.Name}'");
return Task.CompletedTask;
}
}
}