using XP.ImageProcessing.Core; using System.Windows; using System.Windows.Controls; namespace XP.ImageProcessing.CfgControl; /// /// 通用参数配置 UserControl /// 可以根据不同算子的参数自动生成对应的 UI 控件 /// public partial class ProcessorParameterControl : UserControl { private ImageProcessorBase? _currentProcessor; /// /// 参数变化事件 /// public event EventHandler? ParameterChanged; public ProcessorParameterControl() { InitializeComponent(); UpdateNoProcessorText(); } /// /// 更新"未选择算子"的文本 /// private void UpdateNoProcessorText() { txtProcessorName.Text = LocalizationHelper.GetString("NoProcessorSelected"); txtProcessorDescription.Text = LocalizationHelper.GetString("PleaseSelectProcessor"); } /// /// 触发参数变化事件 /// protected virtual void OnParameterChanged() { ParameterChanged?.Invoke(this, EventArgs.Empty); } /// /// 加载算子参数并生成 UI /// public void LoadProcessor(ImageProcessorBase? processor) { _currentProcessor = processor; pnlParameters.Children.Clear(); if (processor == null) { UpdateNoProcessorText(); return; } // 显示算子信息 txtProcessorName.Text = processor.Name; txtProcessorDescription.Text = processor.Description; // 生成参数控件 var parameters = processor.GetParameters(); foreach (var param in parameters) { CreateParameterControl(param); } } /// /// 根据参数类型创建对应的控件 /// private void CreateParameterControl(ProcessorParameter param) { // 如果参数不可见,跳过创建 if (!param.IsVisible) { return; } // 参数标签 var label = new TextBlock { Text = param.DisplayName + ":", Margin = new Thickness(0, 10, 0, 5), FontWeight = FontWeights.Bold, FontSize = 13 }; pnlParameters.Children.Add(label); // 根据参数类型创建不同的控件 UIElement? control = null; if (param.ValueType == typeof(int)) { control = CreateIntegerControl(param); } else if (param.ValueType == typeof(double) || param.ValueType == typeof(float)) { control = CreateDoubleControl(param); } else if (param.ValueType == typeof(bool)) { control = CreateBooleanControl(param); } else if (param.ValueType == typeof(string) && param.Options != null) { control = CreateComboBoxControl(param); } else if (param.ValueType == typeof(string)) { control = CreateTextBoxControl(param); } if (control != null) { pnlParameters.Children.Add(control); // 添加描述标签 if (!string.IsNullOrEmpty(param.Description)) { var desc = new TextBlock { Text = param.Description, Margin = new Thickness(0, 5, 0, 0), FontSize = 11, Foreground = System.Windows.Media.Brushes.Gray, TextWrapping = TextWrapping.Wrap }; pnlParameters.Children.Add(desc); } } } /// /// 创建整数类型控件(Slider + TextBox 或仅 TextBox) /// 当 MinValue 和 MaxValue 都为 null 时,只显示文本框,不显示滑块 /// private UIElement CreateIntegerControl(ProcessorParameter param) { var panel = new StackPanel(); var textBox = new TextBox { Text = param.Value.ToString(), Width = 100, HorizontalAlignment = HorizontalAlignment.Left }; if (param.MinValue != null && param.MaxValue != null) { var slider = new Slider { Minimum = Convert.ToDouble(param.MinValue), Maximum = Convert.ToDouble(param.MaxValue), Value = Convert.ToDouble(param.Value), TickFrequency = 1, IsSnapToTickEnabled = true, Margin = new Thickness(0, 0, 0, 5) }; slider.ValueChanged += (s, e) => { int value = (int)slider.Value; textBox.Text = value.ToString(); _currentProcessor?.SetParameter(param.Name, value); OnParameterChanged(); }; textBox.TextChanged += (s, e) => { if (int.TryParse(textBox.Text, out int value)) { var min = Convert.ToInt32(param.MinValue); var max = Convert.ToInt32(param.MaxValue); if (value >= min && value <= max) { slider.Value = value; } } }; panel.Children.Add(slider); } else { textBox.TextChanged += (s, e) => { if (int.TryParse(textBox.Text, out int value)) { _currentProcessor?.SetParameter(param.Name, value); OnParameterChanged(); } }; } panel.Children.Add(textBox); return panel; } /// /// 创建浮点数类型控件(Slider + TextBox 或仅 TextBox) /// 当 MinValue 和 MaxValue 都为 null 时,只显示文本框,不显示滑块 /// private UIElement CreateDoubleControl(ProcessorParameter param) { var panel = new StackPanel(); var textBox = new TextBox { Text = Convert.ToDouble(param.Value).ToString("F2"), Width = 100, HorizontalAlignment = HorizontalAlignment.Left }; if (param.MinValue != null && param.MaxValue != null) { var slider = new Slider { Minimum = Convert.ToDouble(param.MinValue), Maximum = Convert.ToDouble(param.MaxValue), Value = Convert.ToDouble(param.Value), TickFrequency = 0.1, Margin = new Thickness(0, 0, 0, 5) }; slider.ValueChanged += (s, e) => { double value = Math.Round(slider.Value, 2); textBox.Text = value.ToString("F2"); _currentProcessor?.SetParameter(param.Name, value); OnParameterChanged(); }; textBox.TextChanged += (s, e) => { if (double.TryParse(textBox.Text, out double value)) { var min = Convert.ToDouble(param.MinValue); var max = Convert.ToDouble(param.MaxValue); if (value >= min && value <= max) { slider.Value = value; } } }; panel.Children.Add(slider); } else { textBox.TextChanged += (s, e) => { if (double.TryParse(textBox.Text, out double value)) { _currentProcessor?.SetParameter(param.Name, value); OnParameterChanged(); } }; } panel.Children.Add(textBox); return panel; } /// /// 创建布尔类型控件(CheckBox) /// private UIElement CreateBooleanControl(ProcessorParameter param) { var checkBox = new CheckBox { Content = param.DisplayName, IsChecked = Convert.ToBoolean(param.Value), Margin = new Thickness(0, 5, 0, 0) }; checkBox.Checked += (s, e) => { _currentProcessor?.SetParameter(param.Name, true); OnParameterChanged(); }; checkBox.Unchecked += (s, e) => { _currentProcessor?.SetParameter(param.Name, false); OnParameterChanged(); }; return checkBox; } /// /// 创建下拉框控件(ComboBox) /// private UIElement CreateComboBoxControl(ProcessorParameter param) { var comboBox = new ComboBox { Margin = new Thickness(0, 5, 0, 0), Width = 200, HorizontalAlignment = HorizontalAlignment.Left }; if (param.Options != null) { foreach (var option in param.Options) { comboBox.Items.Add(option); } } comboBox.SelectedItem = param.Value; comboBox.SelectionChanged += (s, e) => { if (comboBox.SelectedItem != null) { _currentProcessor?.SetParameter(param.Name, comboBox.SelectedItem.ToString()!); // 如果是 FilterType 参数,重新加载界面以更新参数可见性 if (param.Name == "FilterType") { LoadProcessor(_currentProcessor); } OnParameterChanged(); } }; return comboBox; } /// /// 创建文本框控件(TextBox) /// private UIElement CreateTextBoxControl(ProcessorParameter param) { var textBox = new TextBox { Text = param.Value?.ToString() ?? "", Margin = new Thickness(0, 5, 0, 0), Width = 200, HorizontalAlignment = HorizontalAlignment.Left }; textBox.TextChanged += (s, e) => { _currentProcessor?.SetParameter(param.Name, textBox.Text); OnParameterChanged(); }; return textBox; } /// /// 获取当前配置的算子 /// public ImageProcessorBase? GetProcessor() { return _currentProcessor; } /// /// 清空参数控件 /// public void Clear() { _currentProcessor = null; pnlParameters.Children.Clear(); UpdateNoProcessorText(); } }