C#自定义控件-更改成员对象的属性后重绘 [英] C# custom control - Redraw after changing a member object's properties

查看:475
本文介绍了C#自定义控件-更改成员对象的属性后重绘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#-.Net4.0,Visual Studio 2010

C# - .Net4.0, Visual Studio 2010

出于某些原因,我使用一个单独的类来存储一些自定义控件的属性(与绘制网格)。这引起了一些问题,因为我希望能够在每次编辑这些值时(通过属性窗口或在运行时)调用 Invalidate()以自动重绘控件。我能想到的最好的解决方案是在我的 GridProperties类中实现INotifyPropertyChanged,在每次调用相关的 set访问器时触发PropertyChanged事件,然后从我的控件类中订阅PropertyChanged事件处理程序以调用重新绘制方法(仅调用Invalidate())。

For certain reasons I'm using a separate class to store some of my custom control's properties (properties to do with drawing a grid). This is causing some problems, since I'd like to be able to call "Invalidate()" any time these values are edited (either via the properties window, or during run-time), to automatically redraw the control. The best solution I could think of was to implement INotifyPropertyChanged within my "GridProperties" class, fire off a PropertyChanged event any time the relevant "set" accessors are called, and then subscribe to the PropertyChanged event handler from my control class to call a "Redraw" method (which just calls Invalidate()).

到目前为止,这是我代码的简化版本。

Here's a shortened version of my code so far.

class MyControl : Control
{
    [Browsable(true)]
    public GridProperties Grid { get; set; }

    public MyControl()
    {
        Grid = new GridValues();
        Grid.Columns = 4;
        Grid.Rows = 4;
        Grid.ShowGridLines = true;

        Grid.PropertyChanged += Redraw;
    }

    private void Redraw (object sender, PropertyChangedEventArgs e)
    {
        Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        //draw gridlines
        //draw columns/ rows
    }
}


class GridProperties : INotifyPropertyChanged
{
    private int columns;
    private int rows;
    private bool showGridLines;

    public int Columns
    {
        get { return columns; }
        set
        {
            if (columns != value)
            {
                columns = value;
                NotifyPropertyChanged("Columns");
            }
        }
    }

    public int Rows...
    //same kinda deal for rows & showGridLines

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(info));
     }
}

我的期望:任何时候Grid都会调用Redraw。 Columns / Grid.Rows / Grid.ShowGridLines值以任何方式更改(希望也可以通过属性窗口更改)。

What I expected: Redraw gets called any time Grid.Columns/ Grid.Rows/ Grid.ShowGridLines values are changed in any way (hopefully through properties window too).

发生了什么:重绘永远不会被调用,除非我做点什么像这样,在MyControl中使用一种全新的方法:

What happens: Redraw never gets called, unless I do something like this, in an entirely new method in MyControl:

Grid.PropertyChanged += Redraw;
Grid.ShowGridLines = false;

这在运行时有效,但是由于我可以设置值,然后每次都调用Invalidate,并且对通过属性窗口进行的任何更改都无济于事。

This works during run-time, but this defeats the point of using an event manager since I can just set the values then call Invalidate every time, and it doesn't help with any changes made through the properties window.

如果有人可以给我一些建议,我做错了或者是否有更好的方法,我真的很感激。老实说,我什至不确定订阅会员的活动经理是否是一种好习惯。

If anyone could give me a heads up on what I'm doing wrong or whether there's a better way, I'd really appreciate it. In all honesty I'm not even sure whether subscribing to a member's event manager is good practice or not.

推荐答案

感谢古斯曼解决方案。我不是从MyControl的构造函数中连接到PropertyChanged,而是从Grid的setter中连接到它,就像这样:

Thanks to Gusman for the solution. Instead of hooking up to PropertyChanged from within MyControl's constructor, I just hooked up to it from within Grid's setter, like so:

private GridProperties grid;
[Browsale(true)]
public GridProperties Grid
{
    get
    {
         return grid;
    }
    set
    {
        if(grid! = null)
            grid.PropertyChanged -= Redraw;

        grid = value;
        grid.PropertyChanged += Redraw;
    }
}

我只能假设某些地方替换了GridProperties对象。无论哪种方式,无论何时访问Grid的设置器,我都只需摘钩/再钩上PropertyChanged事件管理器,现在无论是通过代码还是通过属性窗口更改Grid的值,屏幕都会更新。

I can only assume something is replacing my GridProperties object somewhere. Either way, any time Grid's setter is accessed I just unhook/ and re-hook the PropertyChanged event manager, and now the screen updates whenever Grid's values are changed, whether by code or from the properties window.

这篇关于C#自定义控件-更改成员对象的属性后重绘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆