Răsfoiți Sursa

光源控制器型号切换时通道配置自动同步

优化 LightControllerConfig 的通道集合初始化与同步逻辑,新增 ResizeChannelConfigs 方法,避免重复代码。调整 ViewModel 和 XAML,支持型号变更时自动刷新通道配置,提升 UI 交互体验和数据一致性。
孝锋 徐 7 luni în urmă
părinte
comite
25654224b1

+ 84 - 85
TeamAAS-VM/Models/Lights/LightControllerConfig.cs

@@ -15,7 +15,7 @@ namespace TeamAAS_VP.Models.Lights
     /// 根据所选的 <see cref="LightModel"/> 执行不同的初始化逻辑(如通道数量、串口或 TCP 配置等)。
     /// 该类继承自 Prism 的 <see cref="BindableBase"/>,支持属性变更通知,适用于 WPF MVVM 绑定。
     /// </summary>
-    public class LightControllerConfig: BindableBase
+    public class LightControllerConfig : BindableBase
     {
         private int _Id;
         /// <summary>
@@ -56,9 +56,7 @@ namespace TeamAAS_VP.Models.Lights
         public LightModel LightModel
         {
             get { return _LightModel; }
-            set {
-                SetProperty(ref _LightModel, value);
-            }
+            set { SetProperty(ref _LightModel, value); }
         }
 
         private ObservableCollection<ChannelConfig> _ChannelConfigs;
@@ -117,64 +115,40 @@ namespace TeamAAS_VP.Models.Lights
             switch (LightModel)
             {
                 case LightModel.KCS_KDC_12V60W_4T:
-                    // 该型号为 4 通道的串口控制器(示例),与 setter 中保持一致的初始化
+                    // 该型号为 4 通道的串口控制器(示例)
                     ChannelCount = 4;
                     TcpConfig = null;
-                    SerialPortConfig = new SerialPortConfig();
-                    ChannelConfigs = new ObservableCollection<ChannelConfig>();
-                    for (int i = 0; i < ChannelCount; i++)
+                    if (SerialPortConfig == null)
                     {
-                        ChannelConfigs.Add(new ChannelConfig()
-                        {
-                            LocalIndex = i,
-                            GlobalIndex = i,
-                            Name = $"Channel {i + 1}",
-                            Description = $"Description for Channel {i + 1}",
-                            DefaultBrightness = 100
-                        });
+                        SerialPortConfig = new SerialPortConfig();
                     }
+                    // 调整通道集合,保留已有配置,若不足则追加,若过多则裁剪
+                    ResizeChannelConfigs(ChannelCount);
                     break;
                 case LightModel.KCS_KDC3_24V300W_8T:
                     // 该型号为 8 通道的串口控制器(示例)
                     ChannelCount = 8;
-                    // 对于串口型号,清空/禁用 TCP 配置
                     TcpConfig = null;
-                    // 如果尚未创建串口配置则初始化
                     if (SerialPortConfig == null)
                     {
                         SerialPortConfig = new SerialPortConfig();
                     }
-
-                    // 初始化通道集合,确保包含正确数量的 ChannelConfig
-                    ChannelConfigs = new ObservableCollection<ChannelConfig>();
-                    if (ChannelConfigs.Count != ChannelCount)
-                    {
-                        ChannelConfigs.Clear();
-                        for (int i = 0; i < ChannelCount; i++)
-                        {
-                            // 为每个通道创建默认配置:本地索引/全局索引、名称、描述和默认亮度
-                            ChannelConfigs.Add(new ChannelConfig()
-                            {
-                                LocalIndex = i,
-                                GlobalIndex = i,
-                                Name = $"Channel {i + 1}",
-                                Description = $"Description for Channel {i + 1}",
-                                DefaultBrightness = 100
-                            });
-                        }
-                    }
-
+                    ResizeChannelConfigs(ChannelCount);
                     break;
                 default:
                     // 未知型号:初始化空集合并清空通信配置
-                    ChannelConfigs = new ObservableCollection<ChannelConfig>();
+                    ChannelCount = 0;
+                    if (ChannelConfigs == null)
+                        ChannelConfigs = new ObservableCollection<ChannelConfig>();
+                    else
+                        ResizeChannelConfigs(0);
                     SerialPortConfig = null;
                     TcpConfig = null;
                     break;
             }
         }
 
-        public void Init()
+        public LightControllerConfig Init()
         {
             // 当 LightModel 发生变化时,根据不同型号初始化相关字段与集合。
             switch (LightModel)
@@ -182,72 +156,97 @@ namespace TeamAAS_VP.Models.Lights
                 case LightModel.KCS_KDC_12V60W_4T:
                     // 该型号为 4 通道的串口控制器(示例)
                     ChannelCount = 4;
-                    // 对于串口型号,清空/禁用 TCP 配置
                     TcpConfig = null;
-                    // 如果尚未创建串口配置则初始化
                     if (SerialPortConfig == null)
                     {
                         SerialPortConfig = new SerialPortConfig();
                     }
-
-                    // 初始化通道集合,确保包含正确数量的 ChannelConfig
-                    ChannelConfigs = new ObservableCollection<ChannelConfig>();
-                    if (ChannelConfigs.Count != ChannelCount)
-                    {
-                        ChannelConfigs.Clear();
-                        for (int i = 0; i < ChannelCount; i++)
-                        {
-                            // 为每个通道创建默认配置:本地索引/全局索引、名称、描述和默认亮度
-                            ChannelConfigs.Add(new ChannelConfig()
-                            {
-                                LocalIndex = i,
-                                GlobalIndex = i,
-                                Name = $"Channel {i + 1}",
-                                Description = $"Description for Channel {i + 1}",
-                                DefaultBrightness = 100
-                            });
-                        }
-                    }
-
+                    ResizeChannelConfigs(ChannelCount);
                     break;
                 case LightModel.KCS_KDC3_24V300W_8T:
                     // 该型号为 8 通道的串口控制器(示例)
                     ChannelCount = 8;
-                    // 对于串口型号,清空/禁用 TCP 配置
                     TcpConfig = null;
-                    // 如果尚未创建串口配置则初始化
                     if (SerialPortConfig == null)
                     {
                         SerialPortConfig = new SerialPortConfig();
                     }
-
-                    // 初始化通道集合,确保包含正确数量的 ChannelConfig
-                    ChannelConfigs = new ObservableCollection<ChannelConfig>();
-                    if (ChannelConfigs.Count != ChannelCount)
-                    {
-                        ChannelConfigs.Clear();
-                        for (int i = 0; i < ChannelCount; i++)
-                        {
-                            // 为每个通道创建默认配置:本地索引/全局索引、名称、描述和默认亮度
-                            ChannelConfigs.Add(new ChannelConfig()
-                            {
-                                LocalIndex = i,
-                                GlobalIndex = i,
-                                Name = $"Channel {i + 1}",
-                                Description = $"Description for Channel {i + 1}",
-                                DefaultBrightness = 100
-                            });
-                        }
-                    }
-
+                    ResizeChannelConfigs(ChannelCount);
                     break;
                 default:
                     // 对于未知或未实现的型号,清理所有特定配置并使用默认空集合
-                    ChannelConfigs = new ObservableCollection<ChannelConfig>();
+                    ChannelCount = 0;
+                    if (ChannelConfigs == null)
+                        ChannelConfigs = new ObservableCollection<ChannelConfig>();
+                    else
+                        ResizeChannelConfigs(0);
                     SerialPortConfig = null;
                     TcpConfig = null;
                     break;
             }
+            return this;
+        }
+
+        /// <summary>
+        /// 调整 ChannelConfigs 的数量以匹配 desiredCount:
+        /// - 保留已有前段配置;
+        /// - 若不足则追加新配置;
+        /// - 若过多则从末尾裁剪;
+        /// - 最后规范化每个通道的 LocalIndex/GlobalIndex,并在 Name/Description 为空时填默认值。
+        /// </summary>
+        /// <param name="desiredCount">期望的通道数量</param>
+        private void ResizeChannelConfigs(int desiredCount)
+        {
+            if (ChannelConfigs == null)
+            {
+                ChannelConfigs = new ObservableCollection<ChannelConfig>();
+            }
+
+            int current = ChannelConfigs.Count;
+
+            if (current < desiredCount)
+            {
+                for (int i = current; i < desiredCount; i++)
+                {
+                    ChannelConfigs.Add(new ChannelConfig()
+                    {
+                        LocalIndex = i,
+                        GlobalIndex = i,
+                        Name = $"Channel {i + 1}",
+                        Description = $"Description for Channel {i + 1}",
+                        DefaultBrightness = 100
+                    });
+                }
+            }
+            else if (current > desiredCount)
+            {
+                // 从末尾删除多余通道,保留前面的配置
+                for (int i = current - 1; i >= desiredCount; i--)
+                {
+                    ChannelConfigs.RemoveAt(i);
+                }
+            }
+
+            // 规范化索引与默认文本(不覆盖已有非空 Name/Description)
+            for (int i = 0; i < ChannelConfigs.Count; i++)
+            {
+                var cfg = ChannelConfigs[i];
+                if (cfg == null)
+                    continue;
+
+                cfg.LocalIndex = i;
+                cfg.GlobalIndex = i;
+
+                if (string.IsNullOrWhiteSpace(cfg.Name))
+                    cfg.Name = $"Channel {i + 1}";
+
+                if (string.IsNullOrWhiteSpace(cfg.Description))
+                    cfg.Description = $"Description for Channel {i + 1}";
+
+                // 如果需要可以在此处保留或调整 DefaultBrightness 等字段,但默认不覆盖已有值
+                if (cfg.DefaultBrightness <= 0)
+                    cfg.DefaultBrightness = 100;
+            }
         }
     }
 }

+ 2 - 4
TeamAAS-VM/ViewModels/Setting/AddLightControllerViewModel.cs

@@ -2,7 +2,6 @@ using Prism.Commands;
 using Prism.Mvvm;
 using Prism.Services.Dialogs;
 using System;
-using TeamAAS_VP.Core.Lights;
 using TeamAAS_VP.Models.Lights;
 using TeamAAS_VP.Resources.Languages;
 
@@ -37,7 +36,7 @@ namespace TeamAAS_VP.ViewModels.Setting
 
         public void OnDialogOpened(IDialogParameters parameters)
         {
-            LightController = new LightControllerConfig() { Id = 0, Name = "New Controller", LightModel = TeamAAS_VP.Core.Lights.LightModel.KCS_KDC_12V60W_4T };
+            LightController = new LightControllerConfig() { Id = 0, Name = "New Controller", LightModel = TeamAAS_VP.Core.Lights.LightModel.KCS_KDC_12V60W_4T }.Init();
         }
 
         bool CanExecuteConfirmCommand()
@@ -48,8 +47,7 @@ namespace TeamAAS_VP.ViewModels.Setting
         void ExecuteConfirmCommand()
         {
             var p = new DialogParameters();
-            LightController.Init();
-            p.Add("LightController", LightController);
+            p.Add("LightController", LightController.Init());
             RequestClose?.Invoke(new DialogResult(ButtonResult.OK, p));
         }
 

+ 28 - 0
TeamAAS-VM/ViewModels/SettingViewModel.cs

@@ -423,6 +423,12 @@ namespace TeamAAS_VP.ViewModels
 
         private DelegateCommand _SaveDeviceInfoCommand;
         public DelegateCommand SaveDeviceInfoCommand => _SaveDeviceInfoCommand ?? (_SaveDeviceInfoCommand = new DelegateCommand(ExecuteSaveDeviceInfoCommand));
+
+        private DelegateCommand<object> _LightModelChangedCommand;
+        public DelegateCommand<object> LightModelChangedCommand =>
+            _LightModelChangedCommand ?? (_LightModelChangedCommand = new DelegateCommand<object>(ExecuteLightModelChangedCommand));
+
+
         #endregion
 
         #region 事件
@@ -972,6 +978,28 @@ namespace TeamAAS_VP.ViewModels
                 _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = "完成", Duration = 1 });
             }
         }
+
+        /// <summary>
+        /// 光源型号改变
+        /// </summary>
+        void ExecuteLightModelChangedCommand(object obj)
+        {
+            try
+            {
+                if (obj == null)
+                {
+                    return;
+                }
+                if (obj is LightControllerConfig lc)
+                {
+                    lc.Init();
+                }
+            }
+            catch (Exception)
+            {
+
+            }
+        }
         #endregion
 
         #region 螺丝供料器

+ 8 - 1
TeamAAS-VM/Views/SettingView.xaml

@@ -1510,7 +1510,14 @@
                                       Grid.Column="1"
                                       Margin="10,0"
                                       SelectedItem="{Binding SelectLightController.LightModel,Mode=TwoWay}"
-                                      ItemsSource="{ext:EnumBindingSource EnumType=coreLights:LightModel}" />
+                                      ItemsSource="{ext:EnumBindingSource EnumType=coreLights:LightModel}">
+                                <b:Interaction.Triggers>
+                                    <b:EventTrigger EventName="SelectionChanged">
+                                        <b:InvokeCommandAction Command="{Binding LightModelChangedCommand}"
+                                                               CommandParameter="{Binding SelectLightController}" />
+                                    </b:EventTrigger>
+                                </b:Interaction.Triggers>
+                            </ComboBox>
 
                             <!-- Channel count -->
                             <TextBlock Text="{lex:Loc 通道数, Converter={StaticResource StringFormatConverter},ConverterParameter='{}{0}: '}"