propertygrid同时显示numericupdown和slider

propertygrid同时显示numericupdown和slider

效果

 

image

 

在C# WinForms中,让PropertyGrid同时显示NumericUpDown和Slider控件来编辑同一个数值属性,可以通过自定义UITypeEditor来实现。下面是一个完整的解决方案。

🎯 实现思路概述

方法

核心思路

适用场景

优点

自定义UITypeEditor​

创建下拉编辑器同时包含NumericUpDown和TrackBar

需要直观的数值调整界面

用户体验好,操作直观

TypeConverter转换​

将自定义类型转换为PropertyGrid可识别的格式

复杂对象属性的显示与编辑

灵活性高,可处理复杂数据结构

⚙️ 具体实现步骤

1. 创建包含NumericUpDown和TrackBar的编辑控件

首先创建一个用户控件,同时包含NumericUpDown和TrackBar:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 public class NumericUpDownSliderControl : UserControl
 5 {
 6     private NumericUpDown numericUpDown;
 7     private TrackBar trackBar;
 8     private int _value;
 9     
10     public event EventHandler ValueChanged;
11     
12     public int Value
13     {
14         get { return _value; }
15         set 
16         { 
17             _value = value;
18             numericUpDown.Value = value;
19             trackBar.Value = value;
20         }
21     }
22     
23     public int Minimum
24     {
25         get { return (int)numericUpDown.Minimum; }
26         set 
27         { 
28             numericUpDown.Minimum = value;
29             trackBar.Minimum = value;
30         }
31     }
32     
33     public int Maximum
34     {
35         get { return (int)numericUpDown.Maximum; }
36         set 
37         { 
38             numericUpDown.Maximum = value;
39             trackBar.Maximum = value;
40         }
41     }
42     
43     public NumericUpDownSliderControl()
44     {
45         InitializeComponent();
46         SetupEventHandlers();
47     }
48     
49     private void InitializeComponent()
50     {
51         this.numericUpDown = new NumericUpDown();
52         this.trackBar = new TrackBar();
53         
54         // 配置NumericUpDown
55         numericUpDown.Location = new System.Drawing.Point(0, 0);
56         numericUpDown.Size = new System.Drawing.Size(60, 20);
57         numericUpDown.Minimum = 0;
58         numericUpDown.Maximum = 100;
59         
60         // 配置TrackBar
61         trackBar.Location = new System.Drawing.Point(65, 0);
62         trackBar.Size = new System.Drawing.Size(135, 20);
63         trackBar.Minimum = 0;
64         trackBar.Maximum = 100;
65         trackBar.TickFrequency = 10;
66         
67         // 配置用户控件
68         this.Size = new System.Drawing.Size(200, 45);
69         this.Controls.Add(numericUpDown);
70         this.Controls.Add(trackBar);
71     }
72     
73     private void SetupEventHandlers()
74     {
75         numericUpDown.ValueChanged += (s, e) =>
76         {
77             _value = (int)numericUpDown.Value;
78             trackBar.Value = _value;
79             ValueChanged?.Invoke(this, EventArgs.Empty);
80         };
81         
82         trackBar.Scroll += (s, e) =>
83         {
84             _value = trackBar.Value;
85             numericUpDown.Value = _value;
86             ValueChanged?.Invoke(this, EventArgs.Empty);
87         };
88     }
89 }

2. 创建自定义UITypeEditor

继承UITypeEditor创建自定义编辑器,以下拉形式显示组合控件

 1 using System;
 2 using System.ComponentModel;
 3 using System.Drawing.Design;
 4 using System.Windows.Forms.Design;
 5 
 6 public class NumericUpDownSliderEditor : UITypeEditor
 7 {
 8     public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
 9     {
10         // 设置编辑风格为下拉模式[6](@ref)
11         return UITypeEditorEditStyle.DropDown;
12     }
13     
14     public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
15     {
16         // 获取编辑服务[6](@ref)
17         IWindowsFormsEditorService editorService = 
18             provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
19         
20         if (editorService != null && value is int)
21         {
22             NumericUpDownSliderControl editorControl = new NumericUpDownSliderControl();
23             editorControl.Value = (int)value;
24             editorControl.Minimum = 0; // 可根据需要从属性获取范围
25             editorControl.Maximum = 100;
26             
27             editorControl.ValueChanged += (s, e) =>
28             {
29                 // 值改变时立即更新
30                 value = editorControl.Value;
31             };
32             
33             editorService.DropDownControl(editorControl);
34         }
35         
36         return value;
37     }
38 }

3. 定义使用该编辑器的数据类

创建一个类,其属性使用自定义编辑器

 1 using System.ComponentModel;
 2 
 3 public class Settings
 4 {
 5     private int _sliderValue = 50;
 6     
 7     [DisplayName("数值调节")]
 8     [Description("使用数字框和滑动条同时调节数值")]
 9     [Editor(typeof(NumericUpDownSliderEditor), typeof(System.Drawing.Design.UITypeEditor))]
10     [DefaultValue(50)]
11     public int SliderValue
12     {
13         get { return _sliderValue; }
14         set 
15         { 
16             _sliderValue = value;
17             // 可在此添加属性变化处理逻辑
18         }
19     }
20     
21     // 其他属性...
22     [Category("基本设置")]
23     public string Name { get; set; }
24     
25     [Category("基本设置")]
26     [Description("普通数值属性")]
27     public int NormalValue { get; set; }
28 }

4. 在窗体中使用PropertyGrid

最后,在窗体中添加PropertyGrid并绑定数据对象

 1 public partial class MainForm : Form
 2 {
 3     private PropertyGrid propertyGrid;
 4     private Settings settings;
 5     
 6     public MainForm()
 7     {
 8         InitializeComponent();
 9         SetupPropertyGrid();
10     }
11     
12     private void SetupPropertyGrid()
13     {
14         // 创建PropertyGrid
15         propertyGrid = new PropertyGrid();
16         propertyGrid.Dock = DockStyle.Fill;
17         propertyGrid.ToolbarVisible = true;
18         propertyGrid.HelpVisible = true;
19         
20         // 创建设置对象并绑定
21         settings = new Settings();
22         propertyGrid.SelectedObject = settings;
23         
24         // 添加到窗体
25         this.Controls.Add(propertyGrid);
26         
27         // 可选:添加值改变事件处理
28         propertyGrid.PropertyValueChanged += (s, e) =>
29         {
30             MessageBox.Show($"值已更改为: {settings.SliderValue}");
31         };
32     }
33 }