C#ViewModel对象创建

时间:2018-12-01 03:33:22

标签: c# wpf

我正在阅读一些ViewModel教程,并试图在创建“ Station”对象的窗口中实现它。我的模型站如下:

using System;

namespace Model
{
    public class Station
    {
        public string Name { get; }

        public Station(string name)
        {
            if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Station cannot have no name.");
            Name = name;
        }
    }
}

一个人如何创建一个绑定到WPF表单的ViewModel并创建一个新的Station实例,并使用外观将其添加到存储库或某个列表中?我的问题特别是关于异常以及如何通过绑定处理异常的问题,我还问如何在不使用设置方法的情况下进行操作,因为我阅读的所有教程都使用了设置方法。

我不想使用setter,因为从逻辑上讲,一个工作站必须有一个名称,并且没有名称就不能被实例化。

1 个答案:

答案 0 :(得分:1)

这是我要解决的方法。

导入的名称空间

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.Base

namespace ViewModels.Base
{
    public class ViewModelBase : ReactiveObject
    {
        public virtual Task InitializeAsync(object parameter)
        {
            return Task.CompletedTask;
        }
    }
}

ViewModels

如果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;
        }
    }
}