C#ViewModel对象创建[关闭]

问题描述 投票:-3回答:1

我正在阅读一些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表单并创建新的Station实例并使用外观将其添加到存储库或某个列表的ViewModel?我的问题特别是关于异常以及如何使用绑定处理它们,而且我还要求如何在没有setter的情况下执行它,因为我读过的所有教程都使用setter。

我不想使用setter,因为逻辑上一个工作站需要有一个名称,不应该在没有名称的情况下进行实例化。

c# wpf
1个回答
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为null / empty或者等于_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;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.