You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Property Grid控件选中属性时UI闪烁问题求助

Property Grid编辑时闪烁问题的解决思路

我在使用Property Grid + ComboBox组合时遇到过类似的闪烁问题,结合你的代码和描述,应该是控件重绘触发过于频繁或者双缓冲没开启导致的,下面给你几个针对性的解决方案:

问题回顾

根据ComboBox选中值切换PropertyGrid.SelectedObject并刷新后,编辑Property Grid属性时整个屏幕出现重绘闪烁,切出再切回后消失,且未手动编写过重绘函数。

补充的ComboBox切换代码

if (this.comboBoxHomerSelectSettings.SelectedItem.ToString() == "AppSettings") 
{ 
    this.comboBoxHomerSublist.Visible = false; 
    this.propertyGridEditSettings.SelectedObject = Settings.SingleInstance.SettingsValues.AppSettings; 
} 
else if (this.comboBoxHomerSelectSettings.SelectedItem.ToString() == "WaferSpecificSettings") 
{ 
    this.comboBoxHomerSublist.Visible = true; 
    this.comboBoxHomerSublist.Items.Clear(); 
    for (int i = 0; i < Settings.SingleInstance.SettingsValues.WaferSpeicificSettingsList.WaferSpeicificInformationList.Count;i++ ) 
    { 
        this.comboBoxHomerSublist.Items.Add(Settings.SingleInstance.SettingsValues.WaferSpeicificSettingsList.WaferSpeicificInformationList.ElementAt(i)); 
    } 
    this.comboBoxHomerSublist.SelectedIndex = 0; 
    this.propertyGridEditSettings.SelectedObject = this.comboBoxHomerSublist.SelectedItem; 
} 
else if (this.comboBoxHomerSelectSettings.SelectedItem.ToString() == "BinColorMapping") 
{ 
    this.comboBoxHomerSublist.Visible = true; 
    this.comboBoxHomerSublist.Items.Clear(); 
    for (int i = 0; i < Settings.SingleInstance.SettingsValues.BinColorInfoList.BinColorInformationList.Count; i++) 
    { 
        this.comboBoxHomerSublist.Items.Add(Settings.SingleInstance.SettingsValues.BinColorInfoList.BinColorInformationList.ElementAt(i)); 
    } 
    this.comboBoxHomerSublist.SelectedIndex = 0; 
    this.propertyGridEditSettings.SelectedObject = this.comboBoxHomerSublist.SelectedItem; 
} 
else if (this.comboBoxHomerSelectSettings.SelectedItem.ToString() == "CommonSettings") 
{ 
    this.comboBoxHomerSublist.Visible = false; 
    this.propertyGridEditSettings.SelectedObject = Settings.SingleInstance.SettingsValues.CommonSettings; 
} 
else if (this.comboBoxHomerSelectSettings.SelectedItem.ToString() == "DOETypeMapping") 
{ 
    this.comboBoxHomerSublist.Visible = true; 
    this.comboBoxHomerSublist.Items.Clear(); 
    for (int i = 0; i < Settings.SingleInstance.SettingsValues.DOETypeMapingInfoList.DOETypeMapingInformationList.Count; i++) 
    { 
        this.comboBoxHomerSublist.Items.Add(Settings.SingleInstance.SettingsValues.DOETypeMapingInfoList.DOETypeMapingInformationList.ElementAt(i)); 
    } 
    this.comboBoxHomerSublist.SelectedIndex = 0; 
    this.propertyGridEditSettings.SelectedObject = this.comboBoxHomerSublist.SelectedItem; 
} 
this.propertyGridEditSettings.Refresh();

具体解决方案

1. 给PropertyGrid开启双缓冲

WinForms原生PropertyGrid默认没开启双缓冲,这是导致重绘闪烁的常见原因。你可以自定义一个继承自PropertyGrid的控件,强制开启双缓冲:

public class BufferedPropertyGrid : PropertyGrid
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x02000000; // 启用WS_EX_COMPOSITED样式,实现双缓冲
            return cp;
        }
    }
}

然后把窗体上的propertyGridEditSettings替换成这个自定义控件,基本能解决大部分重绘闪烁问题。

2. 去掉不必要的Refresh调用

看你代码最后手动调用了propertyGridEditSettings.Refresh(),其实当你设置SelectedObject时,PropertyGrid会自动触发刷新,额外的Refresh会导致重复重绘,加重闪烁。直接删掉这行代码试试。

3. 批量更新控件状态,减少重绘次数

在切换ComboBox选项时,你同时修改了子ComboBox的可见性、Items集合,还设置了PropertyGrid的SelectedObject,这些操作会多次触发界面重绘。可以把这些操作包裹在SuspendLayout()和ResumeLayout()之间,让所有变更一次性生效:

this.SuspendLayout(); // 暂停布局更新

// 原来的所有判断逻辑代码...

// 去掉this.propertyGridEditSettings.Refresh();

this.ResumeLayout(false); // 恢复布局,一次性更新界面

这样能避免多次局部重绘导致的闪烁。

4. 给Settings类实现INotifyPropertyChanged接口

如果你的Settings相关类没有实现这个接口,当你在PropertyGrid里编辑属性时,控件无法感知到具体哪个属性变化,只能整个重绘。实现接口后,PropertyGrid只会重绘修改的属性区域,大大减少闪烁:

public class AppSettings : INotifyPropertyChanged
{
    private string _exampleProperty;
    public string ExampleProperty
    {
        get => _exampleProperty;
        set
        {
            if (_exampleProperty != value)
            {
                _exampleProperty = value;
                OnPropertyChanged(nameof(ExampleProperty));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

把所有需要在PropertyGrid中编辑的Settings类都加上这个实现。


内容的提问来源于stack exchange,提问作者Athul Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:22:42