规范类名及命名空间名称
This commit is contained in:
@@ -0,0 +1,377 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using XP.ImageProcessing.Core;
|
||||
|
||||
namespace XP.ImageProcessing.CfgControl;
|
||||
|
||||
/// <summary>
|
||||
/// 通用参数配置 UserControl
|
||||
/// 可以根据不同算子的参数自动生成对应的 UI 控件
|
||||
/// </summary>
|
||||
public partial class ProcessorParameterControl : UserControl
|
||||
{
|
||||
private ImageProcessorBase? _currentProcessor;
|
||||
|
||||
/// <summary>
|
||||
/// 参数变化事件
|
||||
/// </summary>
|
||||
public event EventHandler? ParameterChanged;
|
||||
|
||||
public ProcessorParameterControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
UpdateNoProcessorText();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新"未选择算子"的文�?
|
||||
/// </summary>
|
||||
private void UpdateNoProcessorText()
|
||||
{
|
||||
txtProcessorName.Text = LocalizationHelper.GetString("NoProcessorSelected");
|
||||
txtProcessorDescription.Text = LocalizationHelper.GetString("PleaseSelectProcessor");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发参数变化事件
|
||||
/// </summary>
|
||||
protected virtual void OnParameterChanged()
|
||||
{
|
||||
ParameterChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载算子参数并生�?UI
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据参数类型创建对应的控�?
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建整数类型控件(Slider + TextBox 或仅 TextBox�?
|
||||
/// �?MinValue �?MaxValue 都为 null 时,只显示文本框,不显示滑块
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建浮点数类型控件(Slider + TextBox 或仅 TextBox�?
|
||||
/// �?MinValue �?MaxValue 都为 null 时,只显示文本框,不显示滑块
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建布尔类型控件(CheckBox�?
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建下拉框控件(ComboBox�?
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建文本框控件(TextBox�?
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前配置的算�?
|
||||
/// </summary>
|
||||
public ImageProcessorBase? GetProcessor()
|
||||
{
|
||||
return _currentProcessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空参数控件
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_currentProcessor = null;
|
||||
pnlParameters.Children.Clear();
|
||||
UpdateNoProcessorText();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user