代码之家  ›  专栏  ›  技术社区  ›  Andrey Tsarev

C ViewModel对象创建[关闭]

  •  -3
  • Andrey Tsarev  · 技术社区  · 6 年前

    我正在阅读一些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,并创建一个新的工作站实例,然后使用Facade将其添加到存储库或某个列表中?我的问题特别是关于异常以及如何使用绑定来处理它们,我还询问如何在不使用setter的情况下进行处理,因为我读过的所有教程都使用setter。

    我不想使用setter,因为从逻辑上讲,一个站点必须有一个名称,并且不应该没有名称就被声明。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Sir Rufo    6 年前

    下面是我解决这个问题的方法。

    导入的命名空间

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