Browse Source

新增油源控制界面

luo 1 week ago
parent
commit
aa12af7ecc
27 changed files with 728 additions and 177 deletions
  1. 1 0
      Client/Dynamicloadsimulationdevice/Dynamicloadsimulationdevice.csproj
  2. 103 2
      Client/Dynamicloadsimulationdevice/ViewModels/MainWindowViewModel.cs
  3. 32 0
      Client/IViewModel/Convert/BrushToColorConverter.cs
  4. 32 0
      Client/IViewModel/Convert/MutliBoolConverter.cs
  5. 66 0
      Client/IViewModel/Convert/Type2ViewConverter.cs
  6. 167 0
      Client/IViewModel/ViewModels/DisplayViewModelBase.cs
  7. 160 153
      Client/IViewModel/ViewModels/DisplayViewModelBase{TModel}.cs
  8. 36 0
      Client/IViewModel/ViewModels/IDisplayViewModel.cs
  9. 1 1
      Client/IViewModel/ViewModels/Log/LogViewModel.cs
  10. 3 0
      Client/IViewModel/ViewModels/ViewModelBase.cs
  11. 1 3
      Client/IViewModel/ViewModels/ViewModelBase{TModel}.cs
  12. 77 0
      Client/IViewModel/Views/BaseWindow/BaseDialogWindow.axaml
  13. 16 0
      Client/IViewModel/Views/BaseWindow/BaseDialogWindow.axaml.cs
  14. 1 1
      Client/Language/Zh-CN/Zh-CN.csproj
  15. 1 1
      Client/Language/en-us/en-us.csproj
  16. 1 0
      Client/OilSourceControl/IOilSourceControl/IOilSourceControl.cs
  17. 3 2
      Client/OilSourceControl/OilSourceControl/OilSourceControl.cs
  18. 3 1
      Client/OilSourceControl/OilSourceControl/OilSourceControl.csproj
  19. 4 3
      Client/OilSourceControl/OilSourceControl/View/LEDControl.axaml
  20. 2 1
      Client/OilSourceControl/OilSourceControl/View/OilControlView.axaml
  21. 4 3
      Client/OilSourceControl/OilSourceControl/View/PumpControlView.axaml
  22. 1 1
      Client/OilSourceControl/OilSourceControl/ViewModel/CircuitViewModel.cs
  23. 1 1
      Client/OilSourceControl/OilSourceControl/ViewModel/OilSourceAnalogViewModel.cs
  24. 7 2
      Client/OilSourceControl/OilSourceControl/ViewModel/OilSourceStatusViewModel.cs
  25. 1 1
      Communication/ActiveMQCommunication/ActiveMQCommunication.csproj
  26. 1 1
      Communication/LocalCommunication/LocalCommunication.csproj
  27. 3 0
      Dynamicloadsimulationdevice.sln

+ 1 - 0
Client/Dynamicloadsimulationdevice/Dynamicloadsimulationdevice.csproj

@@ -29,6 +29,7 @@
     <ProjectReference Include="..\..\Avalonia\IconResourceSourceGenerator\IconResourceSourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
     <ProjectReference Include="..\..\Avalonia\IconResource\IconResource.csproj" />
     <ProjectReference Include="..\IViewModel\IViewModel.csproj" />
+    <ProjectReference Include="..\OilSourceControl\IOilSourceControl\IOilSourceControl.csproj" />
     <ProjectReference Include="..\OxyPlot\OxyPlot.Avalonia\OxyPlot.Avalonia.csproj" />
   </ItemGroup>
 </Project>

+ 103 - 2
Client/Dynamicloadsimulationdevice/ViewModels/MainWindowViewModel.cs

@@ -1,10 +1,16 @@
-using Avalonia.Controls;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
 using CommunityToolkit.Mvvm.Input;
 using IModel;
 using IViewModel.ViewModels;
+using IViewModel.Views;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
@@ -12,8 +18,12 @@ using System.Windows.Input;
 
 namespace Dynamicloadsimulationdevice.ViewModels
 {
-    internal class MainWindowViewModel:IViewModel.ViewModels.DisplayViewModelBase<IModel.IModel>
+
+    internal sealed class MainWindowViewModel:IViewModel.ViewModels.DisplayViewModelBase
     {
+        private Dictionary<RuntimeTypeHandle, BaseDialogWindow> opendWindows = new Dictionary<RuntimeTypeHandle, BaseDialogWindow>();
+        private List<IDisplayViewModel> DisplayViewModels = new List<IDisplayViewModel>();
+        private readonly string PluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory+"Plugins");
         private MainWindowViewModel()
         {
             IViewModel.ViewModels.LanguageViewModel.Instance.Init();
@@ -26,9 +36,69 @@ namespace Dynamicloadsimulationdevice.ViewModels
                         break;
                     case nameof(LanguageValueViewModel.MenuAbout):
                         break;
+                    default:
+                        {
+                            var v = DisplayViewModels.FirstOrDefault(x => x.MenuKey == args.Header);
+                            if(v==null)
+                            {
+                                ShowToast("", Avalonia.Controls.Notifications.NotificationType.Error);
+                                return;
+                            }
+                            if(v.ShowTop)
+                            {
+                                if (App.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+                                {
+                                    IViewModel.Views.BaseDialogWindow window = new IViewModel.Views.BaseDialogWindow();
+                                    window.DataContext = v;
+                                    window.ShowDialog(desktop.MainWindow!);
+                                }
+                            }
+                            else
+                            {
+                                var handle = v.GetType().TypeHandle;
+                                if(opendWindows.TryGetValue(handle,out var window))
+                                {
+                                    window.Activate();
+                                }
+                                else
+                                {
+                                    window = new IViewModel.Views.BaseDialogWindow();
+                                    window.DataContext = v;
+                                    opendWindows[handle] = window;
+                                    window.Closed += (_, _) =>
+                                    {
+                                        opendWindows.Remove(handle);
+                                    };
+                                    window.Show();
+                                }
+                            }
+                        }
+                        break;
                 }
             };
             IViewModel.ViewModels.MenuViewModel.Instance.Menus.Add(GetFileMenu());
+            OilSourceControl =IModel.Tools.PluginsLoader.Defalut.Load<IOilSourceControl.IOilSourceControl>(PluginPath).FirstOrDefault();
+            if(OilSourceControl!=null)
+            {
+                var v = GetAssemblyViewModels(OilSourceControl.GetType().Assembly);
+                DisplayViewModels.AddRange(v);
+            }
+           DisplayViewModels.Where(x => x.ShowMenu && !string.IsNullOrEmpty(x.MenuParentKey))
+                .GroupBy(x => x.MenuParentKey)
+                .ToList()
+                .ForEach(x=>
+                {
+                    MenuItemViewModel menuItem = new MenuItemViewModel();
+                    menuItem.Header = x.Key;
+                    x.ToList().ForEach(y =>
+                    {
+                        menuItem.Items.Add(new MenuItemViewModel()
+                        {
+                            Header = y.MenuKey,
+                        });
+                    });
+                    MenuViewModel.Instance.Menus.Add(menuItem);
+                });
             MenuViewModel.Instance.Menus.Add(GetAboutMenu());
         }
         static MainWindowViewModel()
@@ -40,6 +110,8 @@ namespace Dynamicloadsimulationdevice.ViewModels
 
         }
 
+
+        public IOilSourceControl.IOilSourceControl? OilSourceControl { get; private set; }
         public ICommand ClosingCommand =>new RelayCommand<WindowClosingEventArgs>(Closing);
         private void Closing(object? sender, WindowClosingEventArgs? args)
         {
@@ -94,5 +166,34 @@ namespace Dynamicloadsimulationdevice.ViewModels
             return item;
         }
         public static MainWindowViewModel Instance { get; } = new MainWindowViewModel();
+
+
+
+        private List<IDisplayViewModel> GetAssemblyViewModels(Assembly assembly)
+        {
+            List<IDisplayViewModel> vm = new List<IDisplayViewModel>();
+            if (assembly == null) return  new List<IDisplayViewModel>();
+            return assembly.GetTypes()
+                .Where(x => x.IsAssignableTo(typeof(IDisplayViewModel)) && x.IsAnsiClass && !x.IsAbstract)
+                .Where(x =>
+                {
+                    var pro = x.GetProperty("Instance", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public);
+                    if (pro == null) return false;
+                    return pro.PropertyType == x;
+                })
+                .Select(x =>
+                {
+                    var pro = x.GetProperty("Instance", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public);
+
+                    var val = pro?.GetValue(null);
+                    if (val is IDisplayViewModel vm) return vm;
+                    return null;
+                })
+                .Where(x => x != null)
+                .Select(x=>x!)
+                .ToList();
+                
+
+        }
     }
 }

+ 32 - 0
Client/IViewModel/Convert/BrushToColorConverter.cs

@@ -0,0 +1,32 @@
+using Avalonia.Controls;
+using Avalonia.Data.Converters;
+using Avalonia.Media;
+using Avalonia.Media.Immutable;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IViewModel.Convert
+{
+    public sealed class BrushToColorConverter : IValueConverter
+    {
+        public static BrushToColorConverter Instance { get; } = new BrushToColorConverter();
+        public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+        {
+            byte transparency = 255;
+            if(parameter!= null && byte.TryParse(parameter.ToString(), out transparency))
+            {
+            }
+            if(value is ImmutableSolidColorBrush brush) return Color.FromArgb(transparency, brush.Color.R, brush.Color.G, brush.Color.B);
+            return Avalonia.Media.Colors.Transparent;
+        }
+
+        public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 32 - 0
Client/IViewModel/Convert/MutliBoolConverter.cs

@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IViewModel.Convert
+{
+    public sealed class MutliBoolConverter : Avalonia.Data.Converters.IMultiValueConverter
+    {
+        public static MutliBoolConverter Instance { get; } = new MutliBoolConverter();
+        public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
+        {
+            if (values == null || values.Count == 0) return false;
+            var bools = values.Select(x =>
+             {
+                 if (x == null) return false;
+                 if (x is bool b) return b;
+                 else
+                 {
+                     if (bool.TryParse(x.ToString(), out b)) return b;
+                     return false;
+                 }
+             }).ToList();
+            bool v =  true;
+            bools.ForEach(x => v &= x);
+            if (parameter == null) return v;
+            else return !v;
+        }
+    }
+}

+ 66 - 0
Client/IViewModel/Convert/Type2ViewConverter.cs

@@ -0,0 +1,66 @@
+using Avalonia.Controls;
+using Avalonia.Data.Converters;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IViewModel.Convert
+{
+    public sealed class Type2ViewConverter : IValueConverter
+    {
+        public static Type2ViewConverter Instance = new Type2ViewConverter();
+        ConcurrentDictionary<RuntimeTypeHandle, Control> Views = new ConcurrentDictionary<RuntimeTypeHandle,Control>();
+        public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+        {
+            if (value is Type type)
+            {
+                if (parameter != null) return (Control)Activator.CreateInstance(type)!;
+                else
+                {
+                    if (Views.TryGetValue(type.TypeHandle, out var view))
+                    {
+                        if(view.Parent is ContentControl window)
+                        {
+                            window.Content = null;
+                        }
+                        return view;
+                    }
+                    else
+                    {
+                        view = (Control)Activator.CreateInstance(type)!;
+                        Views[type.TypeHandle] = view;
+                        return view;
+                    }
+                }
+            }
+            if(value is IList<Type> types)
+            {
+                if (parameter != null) return types.Where(x => x != null).Select(x => Activator.CreateInstance(x));
+                else
+                {
+                   return types.Where(x => x != null)
+                        .Select(x =>
+                        {
+                            if (Views.TryGetValue(x.TypeHandle, out var view)) return view;
+                            else
+                            {
+                                view = (Control)Activator.CreateInstance(x)!;
+                                Views[x.TypeHandle] = view;
+                                return view;
+                            }
+                        });
+                }
+            }
+            return null;
+        }
+
+        public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 167 - 0
Client/IViewModel/ViewModels/DisplayViewModelBase.cs

@@ -0,0 +1,167 @@
+using CommunityToolkit.Mvvm.Input;
+using IViewModel.Tools;
+using SukiUI.Dialogs;
+using SukiUI.Toasts;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace IViewModel.ViewModels
+{
+    public abstract class DisplayViewModelBase : ViewModelBase, IDisplayViewModel
+    {
+        public virtual bool ShowTop { get; } = false;
+        public virtual bool AppendSeparator { get; }
+        public virtual string MenuKey { get; } = string.Empty;
+        public virtual string MenuParentKey { get; } = string.Empty;
+        public DisplayViewModelBase() : base() { }
+        private protected virtual string Caption => LanguageValueViewModel.Instance.PromptTitle;
+        private protected virtual string Yes => LanguageValueViewModel.Instance.PromptYes;
+        private protected virtual string No => LanguageValueViewModel.Instance.PromptNo;
+        public virtual double Width => double.NaN;
+        public virtual double Height => double.NaN;
+        public virtual bool CanResize => true;
+        [AllowNull]
+        public Action CloseWindowAction { get; set; }
+        public ISukiToastManager ToastManager { get; } = new SukiToastManager();
+        public ISukiDialogManager DialogManager { get; } = new SukiDialogManager();
+        [AllowNull]
+        public virtual Type Content
+        {
+            get => content;
+            set => SetProperty(ref content, value);
+        }
+        private string title = string.Empty;
+        private bool saveIsEnabled = false;
+
+        public bool SaveIsEnabled
+        {
+            get { return saveIsEnabled; }
+            set { SetProperty(ref saveIsEnabled, value); }
+        }
+        [AllowNull]
+        public virtual bool CanCancel { get; } 
+
+
+        public bool ShowError(string msg)
+        {
+
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                .OfType(Avalonia.Controls.Notifications.NotificationType.Error)
+                .WithTitle(Caption)
+                .WithContent(msg)
+                .WithActionButton
+                (Yes, _ => { }, true).TryShow());
+        }
+        public bool ShowAsk(string msg, Action? yesaction = null, Action? noaction = null)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                .OfType(Avalonia.Controls.Notifications.NotificationType.Information)
+                .WithTitle(Caption)
+                .WithContent(msg)
+                .WithActionButton(Yes, _ => yesaction?.Invoke(), true)
+                .WithActionButton(No, _ => noaction?.Invoke(), true)
+                .TryShow());
+        }
+        public bool ShowInfo(string msg)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                  .OfType(Avalonia.Controls.Notifications.NotificationType.Information)
+                  .WithTitle(Caption)
+                  .WithContent(msg)
+                  .WithActionButton
+                  (Yes, _ => { }, true).TryShow());
+        }
+        public bool ShowSuccess(string msg)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                  .OfType(Avalonia.Controls.Notifications.NotificationType.Success)
+                  .WithTitle(Caption)
+                  .WithContent(msg)
+                  .WithActionButton
+                  (Yes, _ => { }, true).TryShow());
+        }
+        public bool ShowWarning(string msg)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                  .OfType(Avalonia.Controls.Notifications.NotificationType.Warning)
+                  .WithTitle(Caption)
+                  .WithContent(msg)
+                  .WithActionButton
+                  (Yes, _ => { }, true).TryShow());
+        }
+
+
+        public void ShowToast(string msg, Avalonia.Controls.Notifications.NotificationType type = Avalonia.Controls.Notifications.NotificationType.Information)
+        {
+            if (ToastManager == null) return;
+            DispatherInovke.Inovke(() => ToastManager.CreateToast()
+                .WithTitle(Caption)
+                .WithContent(msg)
+                .OfType(type)
+                .Dismiss().After(TimeSpan.FromSeconds(3))
+                .Dismiss().ByClicking()
+                .Queue());
+        }
+        private protected bool cansave = false;
+
+        public virtual string OKContent => "Save";
+        public virtual string CancelContent => "Cancel";
+
+
+        public bool SaveClose { get => saveClose; set => SetProperty(ref saveClose, value); }
+        public ICommand SaveCommand => new RelayCommand(async () =>
+        {
+            Save();
+        });
+        private protected virtual void Save()
+        {
+
+        }
+        public virtual void InitData()
+        {
+
+        }
+        public ICommand CancelCommand => new RelayCommand(Cancel);
+
+        public virtual string Title { get => title; set => SetProperty(ref title, value); }
+        public bool ButtonVisibily { get => buttonVisibily; set => SetProperty(ref buttonVisibily, value); }
+
+
+        [AllowNull]
+        private Type content;
+
+
+        protected virtual bool SkipProperty(string? propertyName)
+        {
+            return false;
+        }
+        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName != nameof(SaveClose)) SaveClose = true;
+            base.OnPropertyChanged(e);
+            if (e.PropertyName == nameof(Content)
+                || e.PropertyName == nameof(ButtonVisibily)
+                || e.PropertyName == nameof(SaveCommand)
+                || e.PropertyName == nameof(Title)
+                || e.PropertyName == nameof(SaveIsEnabled)
+                || e.PropertyName == nameof(CancelCommand))
+                return;
+            if (SkipProperty(e.PropertyName)) return;
+            SaveIsEnabled = true;
+        }
+
+
+        private bool buttonVisibily = true;
+        private bool saveClose = true;
+
+        protected virtual void Cancel()
+        {
+        }
+    }
+}

+ 160 - 153
Client/IViewModel/ViewModels/DisplayViewModelBase{TModel}.cs

@@ -13,181 +13,188 @@ using System.Windows.Input;
 
 namespace IViewModel.ViewModels
 {
-    public abstract class DisplayViewModelBase<TModel>:ViewModelBase<TModel> where TModel :IModel.IModel
-    {    public DisplayViewModelBase() : base() { }
-    public DisplayViewModelBase(TModel model):base(model) { }
-        private protected virtual string Caption=>LanguageValueViewModel.Instance.PromptTitle;
-        private protected virtual string Yes =>LanguageValueViewModel.Instance.PromptYes;
-        private protected virtual string No =>LanguageValueViewModel.Instance.PromptNo;
-    public virtual double Width => double.NaN;
-    public virtual double Height => double.NaN;
-    public virtual bool CanResize => true;
-    [AllowNull]
-    public Action CloseWindowAction { get; set; }
-    public ISukiToastManager ToastManager { get; } = new SukiToastManager();
-    public ISukiDialogManager DialogManager { get; } = new SukiDialogManager();
-    [AllowNull]
-    public virtual Type Content
-    {
-        get => content;
-        set => SetProperty(ref content , value); 
-    }
-    private string title = string.Empty;
-    private bool saveIsEnabled= false;
 
-    public bool SaveIsEnabled
+    public abstract class DisplayViewModelBase<TModel> :ViewModelBase<TModel>,IDisplayViewModel where TModel : IModel.IModel
     {
-        get { return saveIsEnabled; }
-        set {SetProperty(ref saveIsEnabled , value); }
-    }
-    [AllowNull]
-    public virtual bool CanCancel { get; } = typeof(TModel).IsAnsiClass && !typeof(TModel).IsAbstract;
+        public virtual bool ShowTop { get; } = false;
+
+        public virtual bool AppendSeparator { get; }
+        public virtual string MenuKey { get; } = string.Empty;
+        public virtual string MenuParentKey { get; } = string.Empty;
+        public DisplayViewModelBase() : base() { }
+        public DisplayViewModelBase(TModel model) : base(model) { }
+        private protected virtual string Caption => LanguageValueViewModel.Instance.PromptTitle;
+        private protected virtual string Yes => LanguageValueViewModel.Instance.PromptYes;
+        private protected virtual string No => LanguageValueViewModel.Instance.PromptNo;
+        public virtual double Width => double.NaN;
+        public virtual double Height => double.NaN;
+        public virtual bool CanResize => true;
+        [AllowNull]
+        public Action CloseWindowAction { get; set; }
+        public ISukiToastManager ToastManager { get; } = new SukiToastManager();
+        public ISukiDialogManager DialogManager { get; } = new SukiDialogManager();
+        [AllowNull]
+        public virtual Type Content
+        {
+            get => content;
+            set => SetProperty(ref content, value);
+        }
+        private string title = string.Empty;
+        private bool saveIsEnabled = false;
 
+        public bool SaveIsEnabled
+        {
+            get { return saveIsEnabled; }
+            set { SetProperty(ref saveIsEnabled, value); }
+        }
+        [AllowNull]
+        public virtual bool CanCancel { get; } = typeof(TModel).IsAnsiClass && !typeof(TModel).IsAbstract;
 
-    public bool ShowError(string msg)
-    {
-        
-        return DispatherInovke.Inovke(()=> DialogManager.CreateDialog()
-            .OfType(Avalonia.Controls.Notifications.NotificationType.Error)
-            .WithTitle(Caption)
-            .WithContent(msg)
-            .WithActionButton
-            (Yes, _ => { }, true).TryShow());
-    }
-    public bool ShowAsk(string msg, Action? yesaction = null, Action? noaction = null)
-    {
-        return DispatherInovke.Inovke(()=> DialogManager.CreateDialog()
-            .OfType(Avalonia.Controls.Notifications.NotificationType.Information)
-            .WithTitle(Caption)
-            .WithContent(msg)
-            .WithActionButton(Yes, _ => yesaction?.Invoke(), true)
-            .WithActionButton(No, _ => noaction?.Invoke(), true)
-            .TryShow());
-    }
-    public bool ShowInfo(string msg)
-    {
-        return DispatherInovke.Inovke(()=> DialogManager.CreateDialog()
-              .OfType(Avalonia.Controls.Notifications.NotificationType.Information)
-              .WithTitle(Caption)
-              .WithContent(msg)
-              .WithActionButton
-              (Yes, _ => { }, true).TryShow());
-    }
-    public bool ShowSuccess(string msg)
-    {
-        return DispatherInovke.Inovke(()=> DialogManager.CreateDialog()
-              .OfType(Avalonia.Controls.Notifications.NotificationType.Success)
-              .WithTitle(Caption)
-              .WithContent(msg)
-              .WithActionButton
-              (Yes, _ => { }, true).TryShow());
-    }
-    public bool ShowWarning(string msg)
-    {
-        return DispatherInovke.Inovke(()=> DialogManager.CreateDialog()
-              .OfType(Avalonia.Controls.Notifications.NotificationType.Warning)
-              .WithTitle(Caption)
-              .WithContent(msg)
-              .WithActionButton
-              (Yes, _ => { }, true).TryShow());
-    }
 
+        public bool ShowError(string msg)
+        {
 
-    public void ShowToast(string msg,Avalonia.Controls.Notifications.NotificationType type = Avalonia.Controls.Notifications.NotificationType.Information)
-    {
-        if (ToastManager == null) return;
-        DispatherInovke.Inovke(()=> ToastManager.CreateToast()
-            .WithTitle(Caption)
-            .WithContent(msg)
-            .OfType(type)
-            .Dismiss().After(TimeSpan.FromSeconds(3))
-            .Dismiss().ByClicking()
-            .Queue());
-    }
-    private protected bool cansave = false;
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                .OfType(Avalonia.Controls.Notifications.NotificationType.Error)
+                .WithTitle(Caption)
+                .WithContent(msg)
+                .WithActionButton
+                (Yes, _ => { }, true).TryShow());
+        }
+        public bool ShowAsk(string msg, Action? yesaction = null, Action? noaction = null)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                .OfType(Avalonia.Controls.Notifications.NotificationType.Information)
+                .WithTitle(Caption)
+                .WithContent(msg)
+                .WithActionButton(Yes, _ => yesaction?.Invoke(), true)
+                .WithActionButton(No, _ => noaction?.Invoke(), true)
+                .TryShow());
+        }
+        public bool ShowInfo(string msg)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                  .OfType(Avalonia.Controls.Notifications.NotificationType.Information)
+                  .WithTitle(Caption)
+                  .WithContent(msg)
+                  .WithActionButton
+                  (Yes, _ => { }, true).TryShow());
+        }
+        public bool ShowSuccess(string msg)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                  .OfType(Avalonia.Controls.Notifications.NotificationType.Success)
+                  .WithTitle(Caption)
+                  .WithContent(msg)
+                  .WithActionButton
+                  (Yes, _ => { }, true).TryShow());
+        }
+        public bool ShowWarning(string msg)
+        {
+            return DispatherInovke.Inovke(() => DialogManager.CreateDialog()
+                  .OfType(Avalonia.Controls.Notifications.NotificationType.Warning)
+                  .WithTitle(Caption)
+                  .WithContent(msg)
+                  .WithActionButton
+                  (Yes, _ => { }, true).TryShow());
+        }
 
-    public virtual string OKContent => "Save";
-    public virtual string CancelContent =>"Cancel";
 
+        public void ShowToast(string msg, Avalonia.Controls.Notifications.NotificationType type = Avalonia.Controls.Notifications.NotificationType.Information)
+        {
+            if (ToastManager == null) return;
+            DispatherInovke.Inovke(() => ToastManager.CreateToast()
+                .WithTitle(Caption)
+                .WithContent(msg)
+                .OfType(type)
+                .Dismiss().After(TimeSpan.FromSeconds(3))
+                .Dismiss().ByClicking()
+                .Queue());
+        }
+        private protected bool cansave = false;
 
-    public bool SaveClose { get => saveClose; set =>SetProperty(ref saveClose , value); }
-    public ICommand SaveCommand => new RelayCommand(async ()=>
-    {
-        if (!cansave) return;
-        Save();
-        if(!savecanclose)
+        public virtual string OKContent => "Save";
+        public virtual string CancelContent => "Cancel";
+
+
+        public bool SaveClose { get => saveClose; set => SetProperty(ref saveClose, value); }
+        public ICommand SaveCommand => new RelayCommand(async () =>
         {
-            cansave = true;
-            SaveClose = false;
-            await Task.Delay(2);
-            await Task.Run(() =>
+            if (!cansave) return;
+            Save();
+            if (!savecanclose)
             {
-                DispatherInovke.Inovke(() => SaveClose = true);
-            });
-            return;
+                cansave = true;
+                SaveClose = false;
+                await Task.Delay(2);
+                await Task.Run(() =>
+                {
+                    DispatherInovke.Inovke(() => SaveClose = true);
+                });
+                return;
+            }
+            cansave = false;
+        });
+        public ICommand CancelCommand => new RelayCommand(Cancel);
+
+        public virtual string Title { get => title; set => SetProperty(ref title, value); }
+        public bool ButtonVisibily { get => buttonVisibily; set => SetProperty(ref buttonVisibily, value); }
+        private protected bool savecanclose = true;
+        protected virtual void Save()
+        {
+            lastModel = default;
+            savecanclose = true;
         }
-        cansave = false;
-    });
-    public ICommand CancelCommand => new RelayCommand(Cancel);
-
-    public virtual string Title { get => title; set =>SetProperty(ref title , value); }
-    public bool ButtonVisibily { get => buttonVisibily; set =>SetProperty(ref buttonVisibily , value); }
-    private protected bool savecanclose = true;
-    protected virtual void Save()
-    {
-        lastModel = default;
-        savecanclose = true;
-    }
 
-    [AllowNull]
-    private Type content;
+        [AllowNull]
+        private Type content;
 
-    public virtual void InitData()
-    {
-        SaveClose = true;
-        cansave = true;
-        if (CanCancel)
+        public virtual void InitData()
+        {
+            SaveClose = true;
+            cansave = true;
+            if (CanCancel)
+            {
+                lastModel = (TModel)Model.Clone();
+                SaveIsEnabled = false;
+            }
+            else
+            {
+                //lastModel = default;
+            }
+        }
+
+        protected virtual bool SkipProperty(string? propertyName)
         {
-            lastModel = (TModel)Model.Clone();
-            SaveIsEnabled = false;
+            return false;
         }
-        else
+        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
         {
-            //lastModel = default;
+            if (e.PropertyName != nameof(SaveClose)) SaveClose = true;
+            base.OnPropertyChanged(e);
+            if (e.PropertyName == nameof(Content)
+                || e.PropertyName == nameof(Model)
+                || e.PropertyName == nameof(ButtonVisibily)
+                || e.PropertyName == nameof(SaveCommand)
+                || e.PropertyName == nameof(Title)
+                || e.PropertyName == nameof(SaveIsEnabled)
+                || e.PropertyName == nameof(CancelCommand))
+                return;
+            if (SkipProperty(e.PropertyName)) return;
+            SaveIsEnabled = true;
         }
-    }
-
-    protected virtual bool SkipProperty(string? propertyName)
-    {
-        return false;
-    }
-    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
-    {
-        if(e.PropertyName !=nameof(SaveClose)) SaveClose = true;
-        base.OnPropertyChanged(e);
-        if (e.PropertyName == nameof(Content)
-            || e.PropertyName == nameof(Model)
-            || e.PropertyName == nameof(ButtonVisibily)
-            || e.PropertyName == nameof(SaveCommand)
-            || e.PropertyName == nameof(Title)
-            || e.PropertyName == nameof(SaveIsEnabled)
-            || e.PropertyName == nameof(CancelCommand))
-            return;
-        if (SkipProperty(e.PropertyName)) return;
-        SaveIsEnabled = true;
-    }
 
 
-    private bool buttonVisibily = true;
-    private bool saveClose = true;
+        private bool buttonVisibily = true;
+        private bool saveClose = true;
 
-    protected virtual void Cancel()
-    {
-        if (CanCancel && lastModel !=null)
+        protected virtual void Cancel()
         {
-            UpDateModel(lastModel);
-            lastModel = default;
+            if (CanCancel && lastModel != null)
+            {
+                UpDateModel(lastModel);
+                lastModel = default;
+            }
         }
     }
-    }
 }

+ 36 - 0
Client/IViewModel/ViewModels/IDisplayViewModel.cs

@@ -0,0 +1,36 @@
+using SukiUI.Dialogs;
+using SukiUI.Toasts;
+using System.Windows.Input;
+
+namespace IViewModel.ViewModels
+{
+    public interface IDisplayViewModel
+    {
+        public bool AppendSeparator { get; }
+        public bool ShowTop { get; }
+        public string MenuParentKey { get; }
+        public Type Content { get; set; }
+        public string MenuKey { get; }
+        public bool ShowMenu => !string.IsNullOrEmpty(MenuKey);
+        public double Width { get; }
+        public double Height { get; }
+        public bool CanResize { get; }
+        public Action CloseWindowAction { get; set; }
+        public ISukiToastManager ToastManager { get; }
+        public ISukiDialogManager DialogManager { get; } 
+        public bool SaveIsEnabled { get; set; }
+        public bool CanCancel { get; }
+        public bool ShowError(string msg);
+        public bool ShowAsk(string msg, Action? yesaction = null, Action? noaction = null);
+        public bool ShowInfo(string msg);
+        public bool ShowSuccess(string msg);
+        public bool ShowWarning(string msg);
+        public void ShowToast(string msg, Avalonia.Controls.Notifications.NotificationType type = Avalonia.Controls.Notifications.NotificationType.Information);
+        public void InitData();
+        public bool SaveClose { get; set; }
+        public ICommand SaveCommand { get; }
+        public ICommand CancelCommand { get; }
+        public string Title { get; set; }
+        public bool ButtonVisibily { get; set; }
+    }
+}

+ 1 - 1
Client/IViewModel/ViewModels/Log/LogViewModel.cs

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 
 namespace IViewModel.ViewModels
 {
-    public sealed class LogViewModel:DisplayViewModelBase<IModel.IModel>
+    public sealed class LogViewModel:DisplayViewModelBase
     {
         public AvaloniaList<IndexValueItemViewModel<LogItemViewModel>> Logs { get; } = new AvaloniaList<IndexValueItemViewModel<LogItemViewModel>>();
         private LogViewModel()

+ 3 - 0
Client/IViewModel/ViewModels/ViewModelBase.cs

@@ -11,6 +11,9 @@ namespace IViewModel.ViewModels
 {
     public abstract class ViewModelBase:ObservableObject
     {
+        public virtual void Init()
+        {
+        }
         [return: NotNull]
         protected EventBroker.EventData<TData> GetEvent<TData>() => (EventBroker.EventData<TData>)EventBroker.Instance.GetEvent<TData>();
 

+ 1 - 3
Client/IViewModel/ViewModels/ViewModelBase{TModel}.cs

@@ -90,9 +90,7 @@ namespace IViewModel.ViewModels
             RefreshUI(nochanged);
         }
 
-        public virtual void Init()
-        {
-        }
+
 
         [AllowNull]
         private protected TModel lastModel;

+ 77 - 0
Client/IViewModel/Views/BaseWindow/BaseDialogWindow.axaml

@@ -0,0 +1,77 @@
+<suki:SukiWindow
+    x:Class="IViewModel.Views.BaseDialogWindow"
+    xmlns="https://github.com/avaloniaui"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:convert="using:IViewModel.Convert"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:local="using:IViewModel"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:suki="https://github.com/kikipoulet/SukiUI"
+    xmlns:vm="using:IViewModel.ViewModels"
+    Title="{local:ResourceBinding Title}"
+    Width="{Binding Width}"
+    Height="{Binding Height}"
+    d:DesignHeight="450"
+    d:DesignWidth="800"
+    CanMaximize="{Binding CanResize}"
+    CanMinimize="False"
+    CanResize="{Binding CanResize}"
+    FontStyle="Normal"
+    FontWeight="Medium"
+    ShowInTaskbar="False"
+    mc:Ignorable="d">
+    <Interaction.Behaviors>
+        <EventTriggerBehavior EventName="Closing">
+            <InvokeCommandAction Command="{Binding CancelCommand}" />
+        </EventTriggerBehavior>
+    </Interaction.Behaviors>
+    <suki:SukiWindow.Hosts>
+        <suki:SukiToastHost Manager="{Binding ToastManager}" />
+        <suki:SukiDialogHost Manager="{Binding DialogManager}" />
+    </suki:SukiWindow.Hosts>
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="*" />
+            <RowDefinition Height="auto" />
+        </Grid.RowDefinitions>
+        <ContentControl Content="{Binding Content, Converter={x:Static convert:Type2ViewConverter.Instance}}" />
+        <StackPanel
+            Grid.Row="1"
+            Height="46"
+            Margin="4"
+            HorizontalAlignment="Center"
+            VerticalAlignment="Center"
+            IsVisible="{Binding ButtonVisibily}"
+            Orientation="Horizontal">
+            <Button
+                Width="86"
+                Command="{Binding SaveCommand}"
+                Content="{local:ResourceBinding OKContent}"
+                IsEnabled="{Binding SaveIsEnabled}">
+                <Interaction.Behaviors>
+                    <EventTriggerBehavior EventName="Click">
+                        <InvokeCommandAction Command="{Binding SaveCommand}" />
+
+                        <CallMethodAction
+                            IsEnabled="{Binding SaveClose}"
+                            MethodName="Close"
+                            TargetObject="{Binding $parent[suki:SukiWindow]}" />
+                    </EventTriggerBehavior>
+                </Interaction.Behaviors>
+            </Button>
+            <Button
+                Width="86"
+                Margin="120,0,0,0"
+                Command="{Binding CancelCommand}"
+                Content="{local:ResourceBinding CancelContent}">
+                <Interaction.Behaviors>
+                    <EventTriggerBehavior EventName="Click">
+                        <InvokeCommandAction Command="{Binding CancelCommand}" />
+
+                        <CallMethodAction MethodName="Close" TargetObject="{Binding $parent[suki:SukiWindow]}" />
+                    </EventTriggerBehavior>
+                </Interaction.Behaviors>
+            </Button>
+        </StackPanel>
+    </Grid>
+</suki:SukiWindow>

+ 16 - 0
Client/IViewModel/Views/BaseWindow/BaseDialogWindow.axaml.cs

@@ -0,0 +1,16 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using CommunityToolkit.Mvvm.Input;
+using System.Windows.Input;
+
+namespace IViewModel.Views;
+
+public partial class BaseDialogWindow : SukiUI.Controls.SukiWindow
+{
+    public BaseDialogWindow()
+    {
+        InitializeComponent();
+    }
+
+}

+ 1 - 1
Client/Language/Zh-CN/Zh-CN.csproj

@@ -10,7 +10,7 @@
     <AvaloniaXamlIlDebuggerLaunch>False</AvaloniaXamlIlDebuggerLaunch>
   </PropertyGroup>
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Client\Dynamicloadsimulationdevice\bin\$(Configuration)\net8.0\Language\$(ProjectName)\&quot;" />
+    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Client\Dynamicloadsimulationdevice\$(OutDir)Language\$(ProjectName)\&quot;" />
   </Target>
   <ItemGroup>
     <PackageReference Include="Avalonia" Version="11.2.5" />

+ 1 - 1
Client/Language/en-us/en-us.csproj

@@ -10,7 +10,7 @@
     <AvaloniaXamlIlDebuggerLaunch>False</AvaloniaXamlIlDebuggerLaunch>
   </PropertyGroup>
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Client\Dynamicloadsimulationdevice\bin\$(Configuration)\net8.0\Language\$(ProjectName)\&quot;" />
+    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Client\Dynamicloadsimulationdevice\$(OutDir)Language\$(ProjectName)\&quot;" />
   </Target>
   <ItemGroup>
     <PackageReference Include="Avalonia" Version="11.2.5" />

+ 1 - 0
Client/OilSourceControl/IOilSourceControl/IOilSourceControl.cs

@@ -14,5 +14,6 @@ namespace IOilSourceControl
         public ViewModelBase ViewModel { get; }
         public Type MainViewType { get; }
         public Type MinViewType { get; }
+        public Type CircuitViewType { get; }
     }
 }

+ 3 - 2
Client/OilSourceControl/OilSourceControl/OilSourceControl.cs

@@ -18,9 +18,10 @@ namespace OilSourceControl
 
         public ViewModelBase ViewModel => OilSourceStatusViewModel.Instance;
 
-        public Type MainViewType => throw new NotImplementedException();
+        public Type MainViewType => OilSourceStatusViewModel.Instance.Content;
 
-        public Type MinViewType => throw new NotImplementedException();
+        public Type MinViewType { get; }= typeof(View.OilMinView);
+        public Type CircuitViewType { get; }= typeof(View.PumpControlView);
 
     }
 }

+ 3 - 1
Client/OilSourceControl/OilSourceControl/OilSourceControl.csproj

@@ -12,5 +12,7 @@
     <ProjectReference Include="..\..\Avalonia\Avalonia.Xaml.Behaviors\Avalonia.Xaml.Behaviors.csproj" />
     <ProjectReference Include="..\IOilSourceControl\IOilSourceControl.csproj" />
   </ItemGroup>
-
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Client\Dynamicloadsimulationdevice\$(OutDir)Plugins\$(ProjectName)\&quot;" />
+  </Target>
 </Project>

+ 4 - 3
Client/OilSourceControl/OilSourceControl/View/LEDControl.axaml

@@ -2,6 +2,7 @@
     x:Class="OilSourceControl.View.LEDControl"
     xmlns="https://github.com/avaloniaui"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:convert="using:IViewModel.Convert"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     d:DesignHeight="450"
@@ -21,9 +22,9 @@
                 VerticalAlignment="Center">
                 <Ellipse.Fill>
                     <RadialGradientBrush Center="50% 50%" GradientOrigin="50% 50%">
-                        <GradientStop Offset="0" Color="{Binding $parent[UserControl].Foreground, Converter={StaticResource BrushToColorConverter}, ConverterParameter=10}" />
-                        <GradientStop Offset="0.7" Color="{Binding $parent[UserControl].Foreground, Converter={StaticResource BrushToColorConverter}, ConverterParameter=180}" />
-                        <GradientStop Offset="1" Color="{Binding $parent[UserControl].Foreground, Converter={StaticResource BrushToColorConverter}}" />
+                        <GradientStop Offset="0" Color="{Binding $parent[UserControl].Foreground, Converter={x:Static convert:BrushToColorConverter.Instance}, ConverterParameter=10}" />
+                        <GradientStop Offset="0.7" Color="{Binding $parent[UserControl].Foreground, Converter={x:Static convert:BrushToColorConverter.Instance}, ConverterParameter=180}" />
+                        <GradientStop Offset="1" Color="{Binding $parent[UserControl].Foreground, Converter={x:Static convert:BrushToColorConverter.Instance}}" />
                     </RadialGradientBrush>
                 </Ellipse.Fill>
             </Ellipse>

+ 2 - 1
Client/OilSourceControl/OilSourceControl/View/OilControlView.axaml

@@ -2,6 +2,7 @@
     x:Class="OilSourceControl.View.OilControlView"
     xmlns="https://github.com/avaloniaui"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:convert="using:IViewModel.Convert"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:ivm="using:IViewModel"
     xmlns:local="using:OilSourceControl"
@@ -15,7 +16,7 @@
     DataContext="{Binding Source={x:Static vm:OilSourceStatusViewModel.Instance}}"
     mc:Ignorable="d">
     <UserControl.IsEnabled>
-        <MultiBinding Converter="{StaticResource MutliBoolConverter}">
+        <MultiBinding Converter="{x:Static convert:MutliBoolConverter.Instance}">
             <Binding Path="IsConnect" />
             <Binding Path="IsRemote" />
             <Binding Path="IsEnabled" />

+ 4 - 3
Client/OilSourceControl/OilSourceControl/View/PumpControlView.axaml

@@ -2,6 +2,7 @@
     x:Class="OilSourceControl.View.PumpControlView"
     xmlns="https://github.com/avaloniaui"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:convert="using:IViewModel.Convert"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:local="using:OilSourceControl"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -87,7 +88,7 @@
                 Height="42"
                 Command="{Binding LoadPressureCommand}">
                 <Button.IsEnabled>
-                    <MultiBinding Converter="{StaticResource MutliBoolConverter}">
+                    <MultiBinding Converter="{x:Static convert:MutliBoolConverter.Instance}">
                         <MultiBinding.Bindings>
                             <Binding Path="!IsLoadPressure" />
                             <Binding Path="IsStart" />
@@ -108,7 +109,7 @@
                 Height="42"
                 Command="{Binding UnloadPressureCommand}">
                 <Button.IsEnabled>
-                    <MultiBinding Converter="{StaticResource MutliBoolConverter}">
+                    <MultiBinding Converter="{x:Static convert:MutliBoolConverter.Instance}">
                         <MultiBinding.Bindings>
                             <Binding Path="IsLoadPressure" />
                             <Binding Path="IsStart" />
@@ -141,7 +142,7 @@
             Height="42"
             Command="{Binding StopCommand}">
             <Button.IsEnabled>
-                <MultiBinding Converter="{StaticResource MutliBoolConverter}">
+                <MultiBinding Converter="{x:Static convert:MutliBoolConverter.Instance}">
                     <MultiBinding.Bindings>
                         <Binding Path="!IsLoadPressure" />
                         <Binding Path="IsStart" />

+ 1 - 1
Client/OilSourceControl/OilSourceControl/ViewModel/CircuitViewModel.cs

@@ -21,7 +21,7 @@ namespace OilSourceControl.ViewModel
         private int waitTime = 2000;
         public CircuitViewModel()
         {
-            //Content = typeof(Views.PumpControlView);
+            Content = typeof(View.PumpControlView);
         }
         public override bool CanCancel => false;
         public CircuitViewModel(CircuitModel model) : this()

+ 1 - 1
Client/OilSourceControl/OilSourceControl/ViewModel/OilSourceAnalogViewModel.cs

@@ -14,7 +14,7 @@ namespace OilSourceControl.ViewModel
     {
         public OilSourceAnalogViewModel()
         {
-            //Content = typeof(Views.OilAnalogView);
+            Content = typeof(View.OilAnalogView);
         }
         public OilSourceAnalogViewModel(OilSourceModel.Models.OilSourceAnalogModel model) : this()
         {

+ 7 - 2
Client/OilSourceControl/OilSourceControl/ViewModel/OilSourceStatusViewModel.cs

@@ -16,13 +16,18 @@ using System.Threading.Tasks;
 namespace OilSourceControl.ViewModel
 {
     internal sealed class OilSourceStatusViewModel:IViewModel.ViewModels.DisplayViewModelBase<OilSourceModel.Models.OilSourceStatusModel>
-    {        public override double Width => 1300;
+    {
+        public override bool AppendSeparator => true;
+        public override string MenuKey => nameof(LanguageValueViewModel.MenuOilSourceControl);
+        public override string MenuParentKey => nameof(LanguageValueViewModel.MenuDevice);
+        public override double Width => 1300;
         public override double Height => 800;
         public override bool CanResize => false;
         private OilSourceStatusViewModel()
         {
+            Title = nameof(LanguageValueViewModel.MenuOilSourceControl);
             ButtonVisibily = false;
-            //Content = typeof(Views.OilControlView);
+            Content = typeof(View.OilControlView);
             Circulate?.UpDateModel(Model.Circulate);
             for (int i = 0; i < Model.OilSourceAnalogs.Count; i++)
             {

+ 1 - 1
Communication/ActiveMQCommunication/ActiveMQCommunication.csproj

@@ -12,7 +12,7 @@
     <Compile Include="..\TcpEventBus\MsgTool.cs" Link="MsgTool.cs" />
   </ItemGroup>
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Avalonia\ShakerApp\bin\$(Configuration)\net8.0\Communication\$(ProjectName)\&quot;" />
+    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Client\Dynamicloadsimulationdevice\$(OutDir)Communication\$(ProjectName)\&quot;" />
   </Target>
   <ItemGroup>
     <PackageReference Include="MessagePack" Version="3.1.3" />

+ 1 - 1
Communication/LocalCommunication/LocalCommunication.csproj

@@ -15,7 +15,7 @@
     </PackageReference>
   </ItemGroup>
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Avalonia\ShakerApp\bin\$(Configuration)\net8.0\Communication\$(ProjectName)\&quot;" />
+    <Exec Command="xcopy /Y /E &quot;$(TargetDir)&quot; &quot;$(SolutionDir)Client\Dynamicloadsimulationdevice\$(OutDir)Communication\$(ProjectName)\&quot;" />
   </Target>
   <ItemGroup>
     <ProjectReference Include="..\ICommunication\ICommunication.csproj" />

+ 3 - 0
Dynamicloadsimulationdevice.sln

@@ -102,6 +102,9 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanguageSourceGenerator", "Client\Language\LanguageSourceGenerator\LanguageSourceGenerator.csproj", "{1F3FB87A-E9A6-4B0A-A476-A2F507634641}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dynamicloadsimulationdevice", "Client\Dynamicloadsimulationdevice\Dynamicloadsimulationdevice.csproj", "{3CABFF42-E9F7-F3EE-D00A-B2767C0A2C38}"
+	ProjectSection(ProjectDependencies) = postProject
+		{4D46BC91-0A6A-8259-D8D4-39AE3BB4EDDA} = {4D46BC91-0A6A-8259-D8D4-39AE3BB4EDDA}
+	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconResource", "Avalonia\IconResource\IconResource.csproj", "{19F1BC1D-AA34-4197-928B-F28FE4EAA146}"
 EndProject