扩展之前的C# WPF项目,明确界面设计(包含首页、数据库查询、增加、修改页面),并使用数据库(以SQLite为例)存储不同兵器的属性

扩展之前的C# WPF项目,明确界面设计(包含首页、数据库查询、增加、修改页面),并使用数据库(以SQLite为例)存储不同兵器的属性。每个兵器类型(枪支、大炮、飞机、坦克、卫星)将有独特的属性,存储在数据库中,并提供详细的兵器特性说明。我会使用DDD模式,提供完整的代码结构和实现细节。


项目结构

WeaponSystem
├── Domain
│   ├── Entities
│   │   ├── Weapon.cs (抽象类)
│   │   ├── Gun.cs
│   │   ├── Cannon.cs
│   │   ├── Aircraft.cs
│   │   ├── Tank.cs
│   │   ├── Satellite.cs
│   ├── Interfaces
│   │   ├── IWeapon.cs
│   │   ├── IWeaponRepository.cs
│   ├── ValueObjects
│   │   ├── WeaponCharacteristics.cs
├── Application
│   ├── Services
│   │   ├── WeaponService.cs
│   ├── DTOs
│   │   ├── WeaponDTO.cs
│   │   ├── GunDTO.cs, CannonDTO.cs, etc.
├── Infrastructure
│   ├── Repositories
│   │   ├── WeaponRepository.cs
│   ├── Data
│   │   ├── WeaponDbContext.cs
├── Presentation
│   ├── ViewModels
│   │   ├── MainViewModel.cs
│   │   ├── HomeViewModel.cs
│   │   ├── QueryViewModel.cs
│   │   ├── AddViewModel.cs
│   │   ├── UpdateViewModel.cs
│   ├── Views
│   │   ├── MainWindow.xaml
│   │   ├── HomeView.xaml
│   │   ├── QueryView.xaml
│   │   ├── AddView.xaml
│   │   ├── UpdateView.xaml

1. 兵器特性详解

每种兵器有通用属性(ID、名称、射程、威力、重量)和独特属性,存储在数据库中。以下是每种兵器的特性和使用场景:

  • 枪支 (Gun):

    • 特性: 轻便、射速快、适合近距离作战,维护成本低。
    • 独特属性:
      • FireRate (射速,单位:发/分钟)
      • AmmoType (弹药类型,如子弹、霰弹)
    • 使用场景: 步兵作战、城市战、快速反应任务。
    • 任务类型: CloseRange(近距离作战)。
  • 大炮 (Cannon):

    • 特性: 射程远、威力大、部署时间长,适合固定阵地。
    • 独特属性:
      • BarrelLength (炮管长度,单位:米)
      • ShellType (炮弹类型,如高爆、穿甲)
    • 使用场景: 远程火力支援、防线压制。
    • 任务类型: LongRange(远程轰炸)。
  • 飞机 (Aircraft):

    • 特性: 高速、机动性强、可执行多种任务(轰炸、侦察)。
    • 独特属性:
      • MaxSpeed (最大速度,单位:马赫)
      • PayloadCapacity (载弹量,单位:吨)
    • 使用场景: 空中支援、战略轰炸、侦察。
    • 任务类型: AirSupport(空中支援)。
  • 坦克 (Tank):

    • 特性: 重装甲、强火力、适合地面推进。
    • 独特属性:
      • ArmorThickness (装甲厚度,单位:毫米)
      • EnginePower (引擎功率,单位:马力)
    • 使用场景: 地面突击、防守阵地。
    • 任务类型: GroundAssault(地面突击)。
  • 卫星 (Satellite):

    • 特性: 太空部署、提供侦察或通信支持。
    • 独特属性:
      • OrbitAltitude (轨道高度,单位:公里)
      • SensorType (传感器类型,如光学、雷达)
    • 使用场景: 情报收集、通信支持。
    • 任务类型: Reconnaissance(侦察)。

2. 领域层 (Domain)

2.1 接口 (IWeapon.cs)
namespace WeaponSystem.Domain.Interfaces
{
    public interface IWeapon
    {
        string Id { get; }
        string Name { get; }
        WeaponCharacteristics Characteristics { get; }
        void UseWeapon(string missionType);
        string GetFeatures();
    }
}
2.2 抽象类 (Weapon.cs)
namespace WeaponSystem.Domain.Entities
{
    public abstract class Weapon : IWeapon
    {
        public string Id { get; protected set; }
        public string Name { get; protected set; }
        public WeaponCharacteristics Characteristics { get; protected set; }

        protected Weapon(string id, string name, WeaponCharacteristics characteristics)
        {
            Id = id;
            Name = name;
            Characteristics = characteristics;
        }

        public abstract void UseWeapon(string missionType);
        public abstract string GetFeatures();
    }
}
2.3 值对象 (WeaponCharacteristics.cs)
namespace WeaponSystem.Domain.ValueObjects
{
    public class WeaponCharacteristics
    {
        public double Range { get; set; }
        public double Power { get; set; }
        public double Weight { get; set; }
        public Dictionary<string, string> SpecificAttributes { get; set; } // 存储独特属性

        public WeaponCharacteristics(double range, double power, double weight, Dictionary<string, string> specificAttributes)
        {
            Range = range;
            Power = power;
            Weight = weight;
            SpecificAttributes = specificAttributes;
        }
    }
}
2.4 具体实体类

Gun.cs为例,其余类类似,仅独特属性不同。

namespace WeaponSystem.Domain.Entities
{
    public class Gun : Weapon
    {
        public Gun(string id, string name, WeaponCharacteristics characteristics)
            : base(id, name, characteristics)
        {
        }

        public override void UseWeapon(string missionType)
        {
            Console.WriteLine($"Gun {Name} used for {missionType}. Effective for close-range infantry support.");
        }

        public override string GetFeatures()
        {
            var fireRate = Characteristics.SpecificAttributes.GetValueOrDefault("FireRate");
            var ammoType = Characteristics.SpecificAttributes.GetValueOrDefault("AmmoType");
            return $"Gun: {Name}, Range: {Characteristics.Range}km, Power: {Characteristics.Power}, Weight: {Characteristics.Weight}t, FireRate: {fireRate}, AmmoType: {ammoType}";
        }
    }

    // Cannon.cs
    public class Cannon : Weapon
    {
        public Cannon(string id, string name, WeaponCharacteristics characteristics)
            : base(id, name, characteristics) { }

        public override void UseWeapon(string missionType)
        {
            Console.WriteLine($"Cannon {Name} used for {missionType}. Ideal for long-range bombardment.");
        }

        public override string GetFeatures()
        {
            var barrelLength = Characteristics.SpecificAttributes.GetValueOrDefault("BarrelLength");
            var shellType = Characteristics.SpecificAttributes.GetValueOrDefault("ShellType");
            return $"Cannon: {Name}, Range: {Characteristics.Range}km, Power: {Characteristics.Power}, Weight: {Characteristics.Weight}t, BarrelLength: {barrelLength}, ShellType: {shellType}";
        }
    }

    // Aircraft.cs, Tank.cs, Satellite.cs 类似实现,略
}
2.5 仓储接口 (IWeaponRepository.cs)
namespace WeaponSystem.Domain.Interfaces
{
    public interface IWeaponRepository
    {
        void Add(Weapon weapon);
        void Update(Weapon weapon);
        void Delete(string id);
        Weapon GetById(string id);
        IEnumerable<Weapon> GetAll();
        IEnumerable<Weapon> QueryByType(string weaponType);
    }
}

3. 应用层 (Application)

3.1 DTOs

为每种兵器定义特定的DTO,包含独特属性。

namespace WeaponSystem.Application.DTOs
{
    public abstract class WeaponDTO
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public double Range { get; set; }
        public double Power { get; set; }
        public double Weight { get; set; }
        public string Type { get; set; }
    }

    public class GunDTO : WeaponDTO
    {
        public string FireRate { get; set; }
        public string AmmoType { get; set; }
    }

    public class CannonDTO : WeaponDTO
    {
        public string BarrelLength { get; set; }
        public string ShellType { get; set; }
    }

    // AircraftDTO, TankDTO, SatelliteDTO 类似,略
}
3.2 服务 (WeaponService.cs)
using WeaponSystem.Domain.Entities;
using WeaponSystem.Domain.Interfaces;

namespace WeaponSystem.Application.Services
{
    public class WeaponService
    {
        private readonly IWeaponRepository _repository;

        public WeaponService(IWeaponRepository repository)
        {
            _repository = repository;
        }

        public void AddWeapon(WeaponDTO dto)
        {
            var characteristics = new WeaponCharacteristics(
                dto.Range, dto.Power, dto.Weight,
                dto switch
                {
                    GunDTO gun => new Dictionary<string, string> { { "FireRate", gun.FireRate }, { "AmmoType", gun.AmmoType } },
                    CannonDTO cannon => new Dictionary<string, string> { { "BarrelLength", cannon.BarrelLength }, { "ShellType", cannon.ShellType } },
                    // 其他类型类似
                    _ => throw new ArgumentException("Invalid weapon type")
                });

            Weapon weapon = dto.Type switch
            {
                "Gun" => new Gun(dto.Id, dto.Name, characteristics),
                "Cannon" => new Cannon(dto.Id, dto.Name, characteristics),
                // 其他类型
                _ => throw new ArgumentException("Invalid weapon type")
            };
            _repository.Add(weapon);
        }

        public void UpdateWeapon(WeaponDTO dto)
        {
            var characteristics = new WeaponCharacteristics(
                dto.Range, dto.Power, dto.Weight,
                dto switch
                {
                    GunDTO gun => new Dictionary<string, string> { { "FireRate", gun.FireRate }, { "AmmoType", gun.AmmoType } },
                    CannonDTO cannon => new Dictionary<string, string> { { "BarrelLength", cannon.BarrelLength }, { "ShellType", cannon.ShellType } },
                    // 其他类型
                    _ => throw new ArgumentException("Invalid weapon type")
                });

            Weapon weapon = dto.Type switch
            {
                "Gun" => new Gun(dto.Id, dto.Name, characteristics),
                "Cannon" => new Cannon(dto.Id, dto.Name, characteristics),
                // 其他类型
                _ => throw new ArgumentException("Invalid weapon type")
            };
            _repository.Update(weapon);
        }

        public void DeleteWeapon(string id) => _repository.Delete(id);

        public WeaponDTO GetWeaponById(string id)
        {
            var weapon = _repository.GetById(id);
            if (weapon == null) return null;

            return weapon switch
            {
                Gun gun => new GunDTO
                {
                    Id = gun.Id,
                    Name = gun.Name,
                    Range = gun.Characteristics.Range,
                    Power = gun.Characteristics.Power,
                    Weight = gun.Characteristics.Weight,
                    Type = "Gun",
                    FireRate = gun.Characteristics.SpecificAttributes.GetValueOrDefault("FireRate"),
                    AmmoType = gun.Characteristics.SpecificAttributes.GetValueOrDefault("AmmoType")
                },
                Cannon cannon => new CannonDTO
                {
                    Id = cannon.Id,
                    Name = cannon.Name,
                    Range = cannon.Characteristics.Range,
                    Power = cannon.Characteristics.Power,
                    Weight = cannon.Characteristics.Weight,
                    Type = "Cannon",
                    BarrelLength = cannon.Characteristics.SpecificAttributes.GetValueOrDefault("BarrelLength"),
                    ShellType = cannon.Characteristics.SpecificAttributes.GetValueOrDefault("ShellType")
                },
                // 其他类型
                _ => throw new ArgumentException("Invalid weapon type")
            };
        }

        public IEnumerable<WeaponDTO> GetAllWeapons() => _repository.GetAll().Select(MapToDTO);
        public IEnumerable<WeaponDTO> QueryWeaponsByType(string weaponType) => _repository.QueryByType(weaponType).Select(MapToDTO);

        private WeaponDTO MapToDTO(Weapon weapon) => weapon switch
        {
            Gun gun => new GunDTO
            {
                Id = gun.Id,
                Name = gun.Name,
                Range = gun.Characteristics.Range,
                Power = gun.Characteristics.Power,
                Weight = gun.Characteristics.Weight,
                Type = "Gun",
                FireRate = gun.Characteristics.SpecificAttributes.GetValueOrDefault("FireRate"),
                AmmoType = gun.Characteristics.SpecificAttributes.GetValueOrDefault("AmmoType")
            },
            // 其他类型
            _ => throw new ArgumentException("Invalid weapon type")
        };

        public string RecommendWeapon(string missionType)
        {
            return missionType switch
            {
                "CloseRange" => "Gun",
                "LongRange" => "Cannon",
                "AirSupport" => "Aircraft",
                "GroundAssault" => "Tank",
                "Reconnaissance" => "Satellite",
                _ => "Unknown mission type"
            };
        }
    }
}

4. 基础设施层 (Infrastructure)

4.1 数据库上下文 (WeaponDbContext.cs)

使用Entity Framework Core和SQLite存储兵器数据。

using Microsoft.EntityFrameworkCore;
using WeaponSystem.Domain.Entities;
using WeaponSystem.Domain.ValueObjects;

namespace WeaponSystem.Infrastructure.Data
{
    public class WeaponDbContext : DbContext
    {
        public DbSet<WeaponEntity> Weapons { get; set; }

        public WeaponDbContext(DbContextOptions<WeaponDbContext> options) : base(options) { }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<WeaponEntity>()
                .OwnsOne(w => w.Characteristics, c =>
                {
                    c.Property(x => x.Range).HasColumnName("Range");
                    c.Property(x => x.Power).HasColumnName("Power");
                    c.Property(x => x.Weight).HasColumnName("Weight");
                    c.Property(x => x.SpecificAttributes).HasConversion(
                        v => System.Text.Json.JsonSerializer.Serialize(v, null),
                        v => System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(v, null));
                });
        }
    }

    public class WeaponEntity
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Type { get; set; }
        public WeaponCharacteristics Characteristics { get; set; }
    }
}
4.2 仓储实现 (WeaponRepository.cs)
using Microsoft.EntityFrameworkCore;
using WeaponSystem.Domain.Entities;
using WeaponSystem.Domain.Interfaces;

namespace WeaponSystem.Infrastructure.Repositories
{
    public class WeaponRepository : IWeaponRepository
    {
        private readonly WeaponDbContext _context;

        public WeaponRepository(WeaponDbContext context)
        {
            _context = context;
        }

        public void Add(Weapon weapon)
        {
            var entity = new WeaponEntity
            {
                Id = weapon.Id,
                Name = weapon.Name,
                Type = weapon.GetType().Name,
                Characteristics = weapon.Characteristics
            };
            _context.Weapons.Add(entity);
            _context.SaveChanges();
        }

        public void Update(Weapon weapon)
        {
            var entity = _context.Weapons.Find(weapon.Id);
            if (entity != null)
            {
                entity.Name = weapon.Name;
                entity.Type = weapon.GetType().Name;
                entity.Characteristics = weapon.Characteristics;
                _context.SaveChanges();
            }
        }

        public void Delete(string id)
        {
            var entity = _context.Weapons.Find(id);
            if (entity != null)
            {
                _context.Weapons.Remove(entity);
                _context.SaveChanges();
            }
        }

        public Weapon GetById(string id)
        {
            var entity = _context.Weapons.Find(id);
            if (entity == null) return null;

            return entity.Type switch
            {
                "Gun" => new Gun(entity.Id, entity.Name, entity.Characteristics),
                "Cannon" => new Cannon(entity.Id, entity.Name, entity.Characteristics),
                // 其他类型
                _ => throw new ArgumentException("Invalid weapon type")
            };
        }

        public IEnumerable<Weapon> GetAll() => _context.Weapons.ToList().Select(MapToWeapon);
        public IEnumerable<Weapon> QueryByType(string weaponType) => _context.Weapons
            .Where(w => w.Type == weaponType)
            .ToList()
            .Select(MapToWeapon);

        private Weapon MapToWeapon(WeaponEntity entity) => entity.Type switch
        {
            "Gun" => new Gun(entity.Id, entity.Name, entity.Characteristics),
            "Cannon" => new Cannon(entity.Id, entity.Name, entity.Characteristics),
            // 其他类型
            _ => throw new ArgumentException("Invalid weapon type")
        };
    }
}

5. 表现层 (Presentation)

5.1 界面设计
  • 首页 (HomeView.xaml): 显示欢迎信息和推荐兵器功能。
  • 数据库查询 (QueryView.xaml): 显示所有兵器,允许按类型筛选。
  • 增加 (AddView.xaml): 提供表单输入兵器属性,动态调整字段。
  • 修改 (UpdateView.xaml): 编辑已有兵器,动态加载属性。
5.1.1 首页 (HomeView.xaml)
<UserControl x:Class="WeaponSystem.Presentation.Views.HomeView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Margin="10">
        <TextBlock Text="Welcome to Weapon System" FontSize="20" Margin="5"/>
        <TextBox Text="{Binding MissionType}" Width="200" Margin="5"/>
        <TextBlock Text="{Binding RecommendedWeapon}" Margin="5"/>
    </StackPanel>
</UserControl>
5.1.2 查询页面 (QueryView.xaml)
<UserControl x:Class="WeaponSystem.Presentation.Views.QueryView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <ComboBox SelectedItem="{Binding SelectedType}" Width="100" Margin="5">
                <ComboBoxItem>All</ComboBoxItem>
                <ComboBoxItem>Gun</ComboBoxItem>
                <ComboBoxItem>Cannon</ComboBoxItem>
                <ComboBoxItem>Aircraft</ComboBoxItem>
                <ComboBoxItem>Tank</ComboBoxItem>
                <ComboBoxItem>Satellite</ComboBoxItem>
            </ComboBox>
            <Button Content="Query" Command="{Binding QueryCommand}" Margin="5"/>
        </StackPanel>
        <DataGrid Grid.Row="1" ItemsSource="{Binding Weapons}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding Id}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Type" Binding="{Binding Type}"/>
                <DataGridTextColumn Header="Range" Binding="{Binding Range}"/>
                <DataGridTextColumn Header="Power" Binding="{Binding Power}"/>
                <DataGridTextColumn Header="Weight" Binding="{Binding Weight}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>
5.1.3 增加页面 (AddView.xaml)
<UserControl x:Class="WeaponSystem.Presentation.Views.AddView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Margin="10">
        <ComboBox SelectedItem="{Binding SelectedWeapon.Type}" Width="100" Margin="5">
            <ComboBoxItem>Gun</ComboBoxItem>
            <ComboBoxItem>Cannon</ComboBoxItem>
            <ComboBoxItem>Aircraft</ComboBoxItem>
            <ComboBoxItem>Tank</ComboBoxItem>
            <ComboBoxItem>Satellite</ComboBoxItem>
        </ComboBox>
        <TextBox Text="{Binding SelectedWeapon.Name}" Width="200" Margin="5" Prompt="Name"/>
        <TextBox Text="{Binding SelectedWeapon.Range}" Width="200" Margin="5" Prompt="Range (km)"/>
        <TextBox Text="{Binding SelectedWeapon.Power}" Width="200" Margin="5" Prompt="Power"/>
        <TextBox Text="{Binding SelectedWeapon.Weight}" Width="200" Margin="5" Prompt="Weight (t)"/>
        <!-- 动态字段,基于兵器类型 -->
        <ContentControl Content="{Binding DynamicFields}"/>
        <Button Content="Add" Command="{Binding AddCommand}" Margin="5"/>
    </StackPanel>
</UserControl>
5.1.4 修改页面 (UpdateView.xaml)

AddView.xaml类似,但预加载选中兵器的属性。

5.2 ViewModel
5.2.1 主ViewModel (MainViewModel.cs)
using WeaponSystem.Application.Services;
using System.Windows.Controls;
using System.Windows.Input;

namespace WeaponSystem.Presentation.ViewModels
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private UserControl _currentView;

        public UserControl CurrentView
        {
            get => _currentView;
            set { _currentView = value; OnPropertyChanged(nameof(CurrentView)); }
        }

        public ICommand HomeCommand { get; }
        public ICommand QueryCommand { get; }
        public ICommand AddCommand { get; }
        public ICommand UpdateCommand { get; }

        public MainViewModel(WeaponService weaponService)
        {
            HomeCommand = new RelayCommand(() => CurrentView = new HomeView { DataContext = new HomeViewModel(weaponService) });
            QueryCommand = new RelayCommand(() => CurrentView = new QueryView { DataContext = new QueryViewModel(weaponService) });
            AddCommand = new RelayCommand(() => CurrentView = new AddView { DataContext = new AddViewModel(weaponService) });
            UpdateCommand = new RelayCommand(() => CurrentView = new UpdateView { DataContext = new UpdateViewModel(weaponService) });
            CurrentView = new HomeView { DataContext = new HomeViewModel(weaponService) };
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public class RelayCommand : ICommand
    {
        private readonly Action _execute;
        public RelayCommand(Action execute) => _execute = execute;
        public event EventHandler CanExecuteChanged;
        public bool CanExecute(object parameter) => true;
        public void Execute(object parameter) => _execute();
    }
}
5.2.2 首页ViewModel (HomeViewModel.cs)
using WeaponSystem.Application.Services;

namespace WeaponSystem.Presentation.ViewModels
{
    public class HomeViewModel : INotifyPropertyChanged
    {
        private readonly WeaponService _weaponService;
        private string _missionType;

        public string MissionType
        {
            get => _missionType;
            set { _missionType = value; OnPropertyChanged(nameof(MissionType)); OnPropertyChanged(nameof(RecommendedWeapon)); }
        }
        public string RecommendedWeapon => _weaponService.RecommendWeapon(MissionType);

        public HomeViewModel(WeaponService weaponService)
        {
            _weaponService = weaponService;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
5.2.3 查询ViewModel (QueryViewModel.cs)
using WeaponSystem.Application.DTOs;
using WeaponSystem.Application.Services;
using System.Collections.ObjectModel;

namespace WeaponSystem.Presentation.ViewModels
{
    public class QueryViewModel : INotifyPropertyChanged
    {
        private readonly WeaponService _weaponService;
        private string _selectedType;

        public ObservableCollection<WeaponDTO> Weapons { get; set; }
        public string SelectedType
        {
            get => _selectedType;
            set { _selectedType = value; OnPropertyChanged(nameof(SelectedType)); QueryWeapons(); }
        }
        public ICommand QueryCommand { get; }

        public QueryViewModel(WeaponService weaponService)
        {
            _weaponService = weaponService;
            Weapons = new ObservableCollection<WeaponDTO>();
            QueryCommand = new RelayCommand(QueryWeapons);
            SelectedType = "All";
        }

        private void QueryWeapons()
        {
            Weapons.Clear();
            var weapons = SelectedType == "All" ? _weaponService.GetAllWeapons() : _weaponService.QueryWeaponsByType(SelectedType);
            foreach (var weapon in weapons)
                Weapons.Add(weapon);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
5.2.4 增加ViewModel (AddViewModel.cs)
using WeaponSystem.Application.DTOs;
using WeaponSystem.Application.Services;
using System.Windows.Controls;

namespace WeaponSystem.Presentation.ViewModels
{
    public class AddViewModel : INotifyPropertyChanged
    {
        private readonly WeaponService _weaponService;
        private WeaponDTO _selectedWeapon;
        private UserControl _dynamicFields;

        public WeaponDTO SelectedWeapon
        {
            get => _selectedWeapon;
            set
            {
                _selectedWeapon = value;
                UpdateDynamicFields();
                OnPropertyChanged(nameof(SelectedWeapon));
            }
        }
        public UserControl DynamicFields
        {
            get => _dynamicFields;
            set { _dynamicFields = value; OnPropertyChanged(nameof(DynamicFields)); }
        }
        public ICommand AddCommand { get; }

        public AddViewModel(WeaponService weaponService)
        {
            _weaponService = weaponService;
            SelectedWeapon = new GunDTO { Id = Guid.NewGuid().ToString(), Type = "Gun" };
            AddCommand = new RelayCommand(AddWeapon);
            UpdateDynamicFields();
        }

        private void AddWeapon()
        {
            _weaponService.AddWeapon(SelectedWeapon);
        }

        private void UpdateDynamicFields()
        {
            DynamicFields = SelectedWeapon.Type switch
            {
                "Gun" => new UserControl
                {
                    Content = new StackPanel
                    {
                        Children =
                        {
                            new TextBox { Text = ((GunDTO)SelectedWeapon).FireRate, Width = 200, Margin = new Thickness(5) },
                            new TextBox { Text = ((GunDTO)SelectedWeapon).AmmoType, Width = 200, Margin = new Thickness(5) }
                        }
                    }
                },
                "Cannon" => new UserControl
                {
                    Content = new StackPanel
                    {
                        Children =
                        {
                            new TextBox { Text = ((CannonDTO)SelectedWeapon).BarrelLength, Width = 200, Margin = new Thickness(5) },
                            new TextBox { Text = ((CannonDTO)SelectedWeapon).ShellType, Width = 200, Margin = new Thickness(5) }
                        }
                    }
                },
                // 其他类型
                _ => new UserControl()
            };
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
5.2.5 修改ViewModel (UpdateViewModel.cs)

AddViewModel.cs类似,但包含从数据库加载已有兵器的逻辑。

5.3 主窗口 (MainWindow.xaml)
<Window x:Class="WeaponSystem.Presentation.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Weapon System" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Margin="5">
            <Button Content="Home" Command="{Binding HomeCommand}" Margin="5"/>
            <Button Content="Query" Command="{Binding QueryCommand}" Margin="5"/>
            <Button Content="Add" Command="{Binding AddCommand}" Margin="5"/>
            <Button Content="Update" Command="{Binding UpdateCommand}" Margin="5"/>
        </StackPanel>
        <ContentControl Grid.Row="1" Content="{Binding CurrentView}"/>
    </Grid>
</Window>
5.4 代码-behind (MainWindow.xaml.cs)
using Microsoft.EntityFrameworkCore;
using WeaponSystem.Application.Services;
using WeaponSystem.Infrastructure.Data;
using WeaponSystem.Infrastructure.Repositories;
using WeaponSystem.Presentation.ViewModels;
using System.Windows;

namespace WeaponSystem.Presentation.Views
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var options = new DbContextOptionsBuilder<WeaponDbContext>()
                .UseSqlite("Data Source=weapons.db")
                .Options;
            var context = new WeaponDbContext(options);
            context.Database.EnsureCreated();
            var weaponService = new WeaponService(new WeaponRepository(context));
            DataContext = new MainViewModel(weaponService);
        }
    }
}

6. 如何运行

  1. 创建WPF项目,添加上述文件。
  2. 安装NuGet包:
    • Microsoft.EntityFrameworkCore.Sqlite
    • System.Text.Json
  3. 确保项目引用正确,运行MainWindow.xaml
  4. 数据库文件weapons.db会在运行时自动创建。
  5. 通过界面切换首页、查询、增加、修改页面,输入或查询兵器数据。

7. 扩展建议

  • 动态表单优化:使用数据模板(DataTemplate)动态生成兵器特定属性的输入字段。
  • 验证逻辑:在WeaponService中添加输入验证(如射程不能为负)。
  • 日志记录:集成Serilog记录操作日志。
  • 单元测试:为WeaponServiceWeaponRepository编写单元测试。
  • UI美化:添加兵器图标、3D模型预览或动画效果。

如果需要更详细的某部分代码或进一步优化,请告诉我!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张工在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值