实现了添加设备的功能,并写了Object对象的扩展CopyTo方法,实现了数据表的创建。

This commit is contained in:
2025-06-12 18:41:46 +08:00
parent ea15ea594a
commit 6ee5f10aed
11 changed files with 154 additions and 36 deletions

View File

@@ -3,6 +3,7 @@ using System.Data;
using System.Windows; using System.Windows;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using PMSWPF.Data.Repositories;
using PMSWPF.Services; using PMSWPF.Services;
using PMSWPF.ViewModels; using PMSWPF.ViewModels;
using PMSWPF.Views; using PMSWPF.Views;
@@ -21,6 +22,7 @@ namespace PMSWPF
{ {
var container = new ServiceCollection(); var container = new ServiceCollection();
container.AddSingleton<NavgatorServices>(); container.AddSingleton<NavgatorServices>();
container.AddSingleton<DevicesRepositories>();
container.AddSingleton<IDeviceDialogService, DeviceDialogService>(); container.AddSingleton<IDeviceDialogService, DeviceDialogService>();
container.AddSingleton<MainViewModel>(); container.AddSingleton<MainViewModel>();
container.AddSingleton<HomeViewModel>(); container.AddSingleton<HomeViewModel>();

View File

@@ -1,10 +1,16 @@
using SqlSugar;
namespace PMSWPF.Data.Entities; namespace PMSWPF.Data.Entities;
[SugarTable("Device")]
public class DbDevice public class DbDevice
{ {
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]//数据库是自增才配自增
public int Id { get; set; } public int Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Description { get; set; } public string Description { get; set; }
public string Ip { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
public bool IsRuning { get; set; } public bool IsRuning { get; set; }

View File

@@ -1,17 +1,29 @@
using PMSWPF.Data.Entities; using PMSWPF.Data.Entities;
using PMSWPF.Excptions;
namespace PMSWPF.Data.Repositories; namespace PMSWPF.Data.Repositories;
public class DevicesRepositories:BaseRepositories public class DevicesRepositories:BaseRepositories
{ {
public DevicesRepositories() public DevicesRepositories():base()
{ {
var tableExist= _db.DbMaintenance.IsAnyTable<DbDevice>();
if (!tableExist)
{
_db.CodeFirst.InitTables<DbDevice>();
}
} }
public async Task<int> Add(DbDevice dbDevice) public async Task<int> Add(DbDevice dbDevice)
{ {
return await _db.Insertable<DbDevice>(dbDevice).ExecuteCommandAsync(); var exist=await _db.Queryable<DbDevice>().Where(d=>d.Name==dbDevice.Name).FirstAsync();
if (exist != null)
{
throw new DbExistException("设备名称已经存在。");
}
var res= await _db.Insertable<DbDevice>(dbDevice).ExecuteCommandAsync();
return res;
} }
public async Task<List<DbDevice>> GetAll() public async Task<List<DbDevice>> GetAll()

View File

@@ -0,0 +1,10 @@
namespace PMSWPF.Excptions;
public class DbExistException: Exception
{
public DbExistException() : base() { }
public DbExistException(string message) : base(message) { }
public DbExistException(string message, System.Exception innerException) : base(message, innerException) { }
}

View File

@@ -0,0 +1,28 @@
using System.Reflection;
namespace PMSWPF.Extensions;
public static class ObjectExtensions
{
/// <summary>
/// 对象转换将source对象上的所有属性的值都转换到target对象上
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
/// <typeparam name="T"></typeparam>
public static void CopyTo<T>(this Object source ,T target)
{
var sourceType = source.GetType();
var targetType = target.GetType();
var sourceProperties = sourceType.GetProperties();
foreach (PropertyInfo sourceProperty in sourceProperties)
{
PropertyInfo targetProperty = targetType.GetProperty(sourceProperty.Name);
if (targetProperty!= null && targetProperty.CanWrite && sourceProperty.CanRead && targetProperty.PropertyType == sourceProperty.PropertyType)
{
object value = sourceProperty.GetValue(source, null);
targetProperty.SetValue(target, value, null);
}
}
}
}

View File

@@ -1,6 +1,20 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace PMSWPF.Models; namespace PMSWPF.Models;
public class Device public partial class Device:ObservableObject
{ {
[ObservableProperty]
private int id;
[ObservableProperty]
private string name;
[ObservableProperty]
private string description ;
[ObservableProperty]
private string ip ;
[ObservableProperty]
private bool isActive ;
[ObservableProperty]
private bool isRuning ;
} }

View File

@@ -8,7 +8,7 @@ public class DeviceDialogService : IDeviceDialogService
{ {
public async Task<Device> ShowAddDeviceDialog(Device device) public async Task<Device> ShowAddDeviceDialog(Device device)
{ {
DeviceDialogViewModel ddvm = new DeviceDialogViewModel() DeviceDialogViewModel ddvm = new DeviceDialogViewModel(device)
{ {
Title = "添加设备" Title = "添加设备"
}; };

View File

@@ -1,4 +1,10 @@
using CommunityToolkit.Mvvm.Input; using System.Windows;
using CommunityToolkit.Mvvm.Input;
using PMSWPF.Data.Entities;
using PMSWPF.Data.Repositories;
using PMSWPF.Excptions;
using PMSWPF.Extensions;
using PMSWPF.Helper;
using PMSWPF.Models; using PMSWPF.Models;
using PMSWPF.Services; using PMSWPF.Services;
using PMSWPF.ViewModels.Dialogs; using PMSWPF.ViewModels.Dialogs;
@@ -9,17 +15,36 @@ namespace PMSWPF.ViewModels;
public partial class DevicesViewModel : ViewModelBase public partial class DevicesViewModel : ViewModelBase
{ {
private readonly IDeviceDialogService _deviceDialogService; private readonly IDeviceDialogService _deviceDialogService;
private readonly DevicesRepositories _devicesRepositories;
public DevicesViewModel(IDeviceDialogService deviceDialogService) public DevicesViewModel(IDeviceDialogService deviceDialogService,DevicesRepositories devicesRepositories)
{ {
_deviceDialogService = deviceDialogService; _deviceDialogService = deviceDialogService;
_devicesRepositories = devicesRepositories;
} }
[RelayCommand] [RelayCommand]
public async void AddDevice() public async void AddDevice()
{ {
Device device = new Device(); try
await _deviceDialogService.ShowAddDeviceDialog(device); {
Device device = new Device();
await _deviceDialogService.ShowAddDeviceDialog(device);
DbDevice dbDevice = new DbDevice();
device.CopyTo<DbDevice>(dbDevice);
await _devicesRepositories.Add(dbDevice);
}
catch (DbExistException e)
{
Console.WriteLine(e);
MessageBox.Show(e.Message);
}
catch (Exception e)
{
Console.WriteLine(e);
MessageBox.Show(e.Message);
}
} }
} }

View File

@@ -1,13 +1,28 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PMSWPF.Extensions;
using PMSWPF.Models;
namespace PMSWPF.ViewModels.Dialogs; namespace PMSWPF.ViewModels.Dialogs;
public partial class DeviceDialogViewModel:ObservableObject public partial class DeviceDialogViewModel:ObservableObject
{ {
private readonly Device _saveDevice;
[ObservableProperty] [ObservableProperty]
private string title="添加设备"; private string title="添加设备";
public DeviceDialogViewModel() [ObservableProperty]
private Device device;
public DeviceDialogViewModel(Device saveDevice)
{ {
_saveDevice = saveDevice;
this.device = new Device();
}
[RelayCommand]
public void AddDevice()
{
this.device.CopyTo<Device>(_saveDevice);
} }
} }

View File

@@ -11,40 +11,46 @@
Title="{Binding Title}" Title="{Binding Title}"
d:DesignHeight="756" d:DesignHeight="756"
d:DesignWidth="700" d:DesignWidth="700"
CloseButtonClick="OnCloseButtonClick"
CloseButtonText="取消" CloseButtonText="取消"
Closed="OnClosed" Closed="OnClosed"
DefaultButton="Primary" DefaultButton="Primary"
PrimaryButtonClick="OnPrimaryButtonClick" PrimaryButtonCommand="{Binding AddDeviceCommand}"
PrimaryButtonText="添加" PrimaryButtonText="添加"
FullSizeDesired="False" FullSizeDesired="False"
IsShadowEnabled="True" IsShadowEnabled="True"
d:DataContext="{d:DesignInstance vmd:DeviceDialogViewModel}" d:DataContext="{d:DesignInstance vmd:DeviceDialogViewModel}"
mc:Ignorable="d"> mc:Ignorable="d">
<ikw:SimpleStackPanel Spacing="12"> <ikw:SimpleStackPanel Spacing="12">
<TextBox ui:ControlHelper.Header="设备名称"
Text="{Binding Device.Name, UpdateSourceTrigger=PropertyChanged}" />
<TextBox ui:ControlHelper.Header="设备描述"
Text="{Binding Device.Description, UpdateSourceTrigger=PropertyChanged}" />
<TextBox <TextBox
ui:ControlHelper.Header="设备IP地址:" ui:ControlHelper.Header="设备IP地址:"
AcceptsReturn="True" AcceptsReturn="True"
Text="{Binding ElementName=dialog, Path=Title, UpdateSourceTrigger=PropertyChanged}" /> Text="{Binding Device.Ip, UpdateSourceTrigger=PropertyChanged}" />
<TextBox ui:ControlHelper.Header="PrimaryButtonText"
Text="{Binding ElementName=dialog, Path=PrimaryButtonText, UpdateSourceTrigger=PropertyChanged}" /> <CheckBox Content="是否启用" IsChecked="{Binding Device.IsActive}" />
<TextBox ui:ControlHelper.Header="SecondaryButtonText" <!-- <TextBox ui:ControlHelper.Header="PrimaryButtonText" -->
Text="{Binding ElementName=dialog, Path=SecondaryButtonText, UpdateSourceTrigger=PropertyChanged}" /> <!-- Text="{Binding ElementName=dialog, Path=PrimaryButtonText, UpdateSourceTrigger=PropertyChanged}" /> -->
<TextBox ui:ControlHelper.Header="CloseButtonText" <!-- <TextBox ui:ControlHelper.Header="SecondaryButtonText" -->
Text="{Binding ElementName=dialog, Path=CloseButtonText, UpdateSourceTrigger=PropertyChanged}" /> <!-- Text="{Binding ElementName=dialog, Path=SecondaryButtonText, UpdateSourceTrigger=PropertyChanged}" /> -->
<ComboBox <!-- <TextBox ui:ControlHelper.Header="CloseButtonText" -->
ui:ControlHelper.Header="DefaultButton" <!-- Text="{Binding ElementName=dialog, Path=CloseButtonText, UpdateSourceTrigger=PropertyChanged}" /> -->
ItemsSource="{Binding Source={x:Type ui:ContentDialogButton}}" <!-- <ComboBox -->
SelectedItem="{Binding ElementName=dialog, Path=DefaultButton}" /> <!-- ui:ControlHelper.Header="DefaultButton" -->
<CheckBox Content="FullSizeDesired" IsChecked="{Binding ElementName=dialog, Path=FullSizeDesired}" /> <!-- ItemsSource="{Binding Source={x:Type ui:ContentDialogButton}}" -->
<CheckBox Content="IsShadowEnabled" IsChecked="{Binding ElementName=dialog, Path=IsShadowEnabled}" /> <!-- SelectedItem="{Binding ElementName=dialog, Path=DefaultButton}" /> -->
<StackPanel> <!-- -->
<Button Click="TryOpenAnother" Content="Try to open another ContentDialog" /> <!-- <CheckBox Content="IsShadowEnabled" IsChecked="{Binding ElementName=dialog, Path=IsShadowEnabled}" /> -->
<TextBlock <!-- <StackPanel> -->
x:Name="ErrorText" <!-- <Button Click="TryOpenAnother" Content="Try to open another ContentDialog" /> -->
Margin="0,8,0,0" <!-- <TextBlock -->
Foreground="{DynamicResource SystemControlErrorTextForegroundBrush}" <!-- x:Name="ErrorText" -->
Visibility="Collapsed" /> <!-- Margin="0,8,0,0" -->
</StackPanel> <!-- Foreground="{DynamicResource SystemControlErrorTextForegroundBrush}" -->
<!-- Visibility="Collapsed" /> -->
<!-- </StackPanel> -->
</ikw:SimpleStackPanel> </ikw:SimpleStackPanel>
</ui:ContentDialog> </ui:ContentDialog>

View File

@@ -41,8 +41,8 @@ public partial class DeviceDialog
private void OnClosed(ContentDialog sender, ContentDialogClosedEventArgs args) private void OnClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
{ {
ErrorText.Text = string.Empty; // ErrorText.Text = string.Empty;
ErrorText.Visibility = Visibility.Collapsed; // ErrorText.Visibility = Visibility.Collapsed;
} }
} }