【问题标题】:How do I "Invalidate" after adding items to a collection property?将项目添加到集合属性后如何“无效”?
【发布时间】:2023-04-08 09:29:02
【问题描述】:

我正在创建一个自定义控件,其中我正在创建“列表”类型的属性

Sections 是一个公共类,有 4 个属性。

控件中的代码如下所示:

    public partial class genericGauge : Control
{
        public genericGauge()
        {
            InitializeComponent();
        }

// Stripped out code not needed for this issue question.

        private List<Sections> indicators = new List<Sections>();

        public List<Sections> Indicators
        {
            get
            { 
                return indicators;                
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            // Stripped out code not needed for this issue question.
        }

}

Sections 类如下:

public class Sections
    {
        private string header = "Section1";        
        public string Header
        {
            get {return header;}
            set 
            {
                header = value;
            }
        }

        private float startvalue = 0.0f;        
        public float StartValue 
        {
            get { return startvalue; }
            set
            {
                startvalue = value;
            }
        }

        private float sweepvalue = 0.0f;       
        public float SweepValue
        {
            get { return sweepvalue; }
            set
            {
                sweepvalue = value;
            }
        }

        private Color sectioncolor = new Color();        
        public Color SectionColor
        {
            get {return sectioncolor;}
            set
            {
                sectioncolor = value;
            }
        }
    }

除了当我在设计时使用属性浏览器类型编辑器将项目添加到集合中时,一切似乎都正常工作,控件不会重新绘制以反映添加到集合中的内容。

当我在我的测试表单上单击控件外部时,它会被重新绘制。 通常使用简单的属性我会使用 Invalidate,但这在这里似乎是不可能的。 我还尝试了除 List 之外的其他集合类型,它允许有一个 set 访问器,但仍然不会调用 Invalidate。我认为这意味着永远不会调用 SET。

我知道如何让它与可扩展属性一起使用,但我没有找到如何使用集合进行此更新。

我希望有人可以帮助我。 提前致谢。

【问题讨论】:

  • 下次请相应地标记问题。
  • 这和不提高收藏有什么关系吗?我想设计师仍然使用组件模型并且没有 collectionchanged 通知,控件不知道内部有任何更改 - (免责声明:这个答案可能是谎言!)
  • PaintEventArgs 是 WinForms,我相信。
  • @Felix KLing - 对不起。我试图添加标签,但我想我太快了:)
  • @Bob - 这是一个winform自定义控件

标签: c# winforms collections properties


【解决方案1】:

当使用您的示例时,指标属性无法在属性窗口中进行编辑。所以我对其进行了一些更改。

我添加了一个新类:

// Added this class to deal with the Sections class
public class SectionObservable : ObservableCollection<Sections>
{
        // Added a few methods here for creating a designtime collection if I need to.
}

然后我按照你的建议进行了更改

public genericGauge()
{
            InitializeComponent();
            this.indicators.CollectionChanged += this.IndicatorsCollectionChanged;  // your suggestion
}

并改成这样的属性:

private SectionObservable indicators = new SectionObservable(); // using the SectionObservable class instead 

        public SectionObservable Indicators // using the SectionObservable class instead 
        {
            get
            { 
                return indicators;                
            }
        }

        private void IndicatorsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) // your suggestion
        {
            this.Invalidate();
        }

现在可以作为一个护身符。 非常感谢。我很高兴看到有可能如此快速地获得帮助。我非常喜欢这个论坛。

【讨论】:

    【解决方案2】:

    不要使用 List 类,而是使用 ObservableCollection 类,并使用它来在列表中添加或删除新部分时获得通知。

    private ObservableCollection<Sections> indicators = new ObservableCollection<Sections>();
    
    public IList<Sections> Indicators
    {
        get
        { 
            return indicators;                
        }
    }
    
    public genericGauge()
    {
        InitializeComponent();
    
        this.indicators.CollectionChanged += this.IndicatorsCollectionChanged;
    }
    
    private void IndicatorsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // possibly inspect the NotifyCollectionChangedEventArgs to see if it's a change that should cause a redraw.
    
        // or not.
        this.Invalidate();
    }
    

    【讨论】:

    • 这对我很有用。至少它给了我一个想法。如果我想展示我是如何通过您的代码使其工作的,我只是回答我自己的问题吗?
    • 如果超过几句话,是的,请回答您自己的问题。如果它很短,我会把它放在评论中。
    • 好的。我无法回答我自己的问题。我的名声不够好:)
    • 我将在 8 小时内发布我的更改,当我被允许回答时 :)
    猜你喜欢
    • 2011-09-13
    • 2019-08-06
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    相关资源
    最近更新 更多