winform中,自定义控件,添加了一个集合属性,为其添加成员,没有立即刷新,什么问题?

eric1162640737 2012-11-14 10:57:38
现象如题,集合中的项被添加上去了,但没有立即重绘,代码大致如下,小弟只是想如何实现这个功能,例如:
public class myRect
{
...//定义了属性等...
}
public partial class Userconrol : Control
{
private MyRectCollectin myRect = new MyRectCollectin ()
public class MyRectCollectin : CollectionBase
{
public myRect this[int index]
{
get
{
return (myRect)List[index];
}
}
public void Add(myRect rect)
{
List.Add(rect);
}
public void Remove(int index)
{
if (index > Count - 1 || index < 0)
{
MessageBox.Show("Index not valid!");
}
else
{
List.RemoveAt(index);
}
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyCircleCollection MyRect
{
get
{
return myCircle;
}
}
override onPaint()
{...}//包含了画集合中的图像
}
...全文
1147 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjfe_cn 2014-02-27
  • 打赏
  • 举报
回复
你的这个问题是如何解决的
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 11 楼 qiaohuyue 的回复:
你的委托的时间有没有被执行,如果没有被执行,你需要先抛出,后回掉处理。
请问如何判断委托事件有没有被执行?比如在design time下我添加了一个圆圈吧,然后run一下,itemchanged事件这时被调用了,圆圈也在控件上画出来了,但是如果我在propertygrid中再添加一个圆圈在集合里,那么第二个圆圈没有被画上去,但是把鼠标移到控件内,那个圆圈就出来了.因为我在mouseenter中进行了重绘.
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 12 楼 ojlovecd 的回复:
引用 10 楼 eric1162640737 的回复:引用 9 楼 ojlovecd 的回复:try: C# code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 public partial class Userconrol……
public class MyCircle 
    {
        private Point position;
        private int radius;
        public Point Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
            }
        }
        public int Radius
        {
            get
            {
                return radius;
            }
            set
            {
                radius = value;
            }
        }
    }
    public partial class MyButton : Control
    {
 	public MyCircleCollection m_MyCircle = new MyCircleCollection();
    	public MyButton()
        {
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
            m_MyCircle.ItemChanged += OnItemChanged;
        }
        public void OnItemChanged(object sender,EventArgs e)
        {
            this.Invalidate();
        }
        public class MyCircleCollection : CollectionBase
        {   
            public event EventHandler ItemChanged;

            public MyCircle this[int index]
            {
                get
                {
                    return (MyCircle)List[index];
                }
            }
            public void Add(MyCircle circle)
            {
                List.Add(circle);
                ItemChanged(this, null);
            }
            public void Remove(int index)
            {
                if (index > Count - 1 || index < 0)
                {
                    MessageBox.Show("Index not valid!");
                }
                else
                {
                    List.RemoveAt(index);
                }
                ItemChanged(this, null);
            }
           
        }
 	protected override void OnPaint(PaintEventArgs e)
        {
		if (MyCircle.Count != 0)
            {
                foreach (MyCircle c in MyCircle)
                {
                    e.Graphics.DrawEllipse(Pens.Black, c.Position.X, c.Position.Y, c.Radius, c.Radius);//Draw circle
                }
            }
        }
}
大致是这样,就是在一个自定义控件上画圆圈,其实和你的代码差不多.但是不起效果.
我姓区不姓区 2012-11-15
  • 打赏
  • 举报
回复
引用 10 楼 eric1162640737 的回复:
引用 9 楼 ojlovecd 的回复:try: C# code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 public partial class Userconrol : Control { public Us……
最好能把你完整的代码贴出来看看
XBodhi. 2012-11-15
  • 打赏
  • 举报
回复
你的委托的时间有没有被执行,如果没有被执行,你需要先抛出,后回掉处理。
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 9 楼 ojlovecd 的回复:
try: C# code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 public partial class Userconrol : Control { public Userconro……
试过了,仍然没有立即刷新,添加集合中新的项时,在add处添加断点,似乎并没有走进去.因此没有触发这个事件,但是集合中的count确实增加了1.
我姓区不姓区 2012-11-15
  • 打赏
  • 举报
回复
try:

        public partial class Userconrol : Control
        {
            public Userconrol()
            {
                myRect.MyRectChanged += myRect_MyRectChanged;
            }

            void myRect_MyRectChanged(object sender, EventArgs e)
            {
                Invalidate();
            }

            private MyRectCollectin myRect = new MyRectCollectin();

            public class MyRectCollectin : CollectionBase
            {
                public event EventHandler MyRectChanged;

                public myRect this[int index]
                {
                    get
                    {
                        return (myRect)List[index];
                    }
                }
                public void Add(myRect rect)
                {
                    List.Add(rect);
                    if (MyRectChanged != null)
                        MyRectChanged(rect, null);
                }
                public void Remove(int index)
                {
                    if (index > Count - 1 || index < 0)
                    {
                        MessageBox.Show("Index not valid!");
                    }
                    else
                    {
                        List.RemoveAt(index);
                        if (MyRectChanged != null)
                            MyRectChanged(index, null);
                    }
                }
            }
        }

eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 6 楼 ynb119 的回复:
感觉你的处理逻辑存在问题。不是没有触发,是没给它响应的时间。 invalidate 之后调用 update试试。或者直接调用refresh试试。 this.invalidate(); this.update(); 或者 this.refresh();
对,但是什么时候响应呢?应该是添加了新的项,或者是删除了项,又或者更改了项的属性值是进行刷新,那么我要对myRect添加事件,当集合里面的内容有变化时,进行invalidate.但是如何为myRect添加事件,我不太清楚
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 5 楼 gefangliang 的回复:
在Load里面加Invalidate
这样不能解决问题,我在design time状态下要及时刷新,而不是run time下
枫桦沐阳 2012-11-15
  • 打赏
  • 举报
回复
感觉你的处理逻辑存在问题。不是没有触发,是没给它响应的时间。 invalidate 之后调用 update试试。或者直接调用refresh试试。 this.invalidate(); this.update(); 或者 this.refresh();
心灵彩虹 2012-11-15
  • 打赏
  • 举报
回复
在Load里面加Invalidate
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 3 楼 ojlovecd 的回复:
C# code?12345 public void Add(myRect rect) { List.Add(rect); //试试在这里进行重绘 }
不行,那里没有办法调用invalidate,但是我在add和remove下添加了事件,但似乎只有初始化控件的时候触发了事件,其他时候都没有触发.
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 19 楼 ojlovecd 的回复:
这个我解决不了…… 您接着等大神吧, good luck
你那么多勋章已经是大神了~没关系.谢谢你帮忙啊~
我姓区不姓区 2012-11-15
  • 打赏
  • 举报
回复
这个我解决不了…… 您接着等大神吧, good luck
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 17 楼 ojlovecd 的回复:
引用 16 楼 eric1162640737 的回复:引用 15 楼 ojlovecd 的回复:测试了一下,没有问题: C# code?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636……
我觉得应该可以做到啊,现在,添加完后,只需要拉动一下控件,那个圆就显示上去了,因为控件重绘了,但我只是希望它添加完后立即显示上去,这个需求我觉得挺正常的啊...
我姓区不姓区 2012-11-15
  • 打赏
  • 举报
回复
引用 16 楼 eric1162640737 的回复:
引用 15 楼 ojlovecd 的回复:测试了一下,没有问题: C# code?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677……
啥意思?你要在设计视图那通过属性窗口添加,然后在设计视图里就想看见画的圆? 有意义吗?
eric1162640737 2012-11-15
  • 打赏
  • 举报
回复
引用 15 楼 ojlovecd 的回复:
测试了一下,没有问题: C# code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 pub……
您这样用代码去添加的确没问题,要直接在属性栏上更改,就像更改其他控件一样.点击MyCircle属性,会跳出一个dialog,然后添加半径圆心.点击ok,关闭dialog,这时应该添加的圆已经画在控件上了,但是实际却没有.代码也的确生成了.就是没有重绘.
我姓区不姓区 2012-11-15
  • 打赏
  • 举报
回复
测试了一下,没有问题:

    public class MyCircle
    {
        private Point position;
        private int radius;
        public Point Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
            }
        }
        public int Radius
        {
            get
            {
                return radius;
            }
            set
            {
                radius = value;
            }
        }
    }
    public partial class MyButton : Control
    {
        public MyCircleCollection m_MyCircle = new MyCircleCollection();
        public MyButton()
        {
            //这句得去掉this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
            m_MyCircle.ItemChanged += OnItemChanged;
        }
        public void OnItemChanged(object sender, EventArgs e)
        {
            this.Invalidate();
        }
        public class MyCircleCollection : CollectionBase
        {
            public event EventHandler ItemChanged;

            public MyCircle this[int index]
            {
                get
                {
                    return (MyCircle)List[index];
                }
            }
            public void Add(MyCircle circle)
            {
                List.Add(circle);
                ItemChanged(this, null);
            }
            public void Remove(int index)
            {
                if (index > Count - 1 || index < 0)
                {
                    MessageBox.Show("Index not valid!");
                }
                else
                {
                    List.RemoveAt(index);
                }
                ItemChanged(this, null);
            }

        }


        protected override void OnPaint(PaintEventArgs e)
        {
            if (m_MyCircle.Count != 0)
            {
                foreach (MyCircle c in m_MyCircle)
                {
                    e.Graphics.DrawEllipse(Pens.Black, c.Position.X, c.Position.Y, c.Radius, c.Radius);//Draw circle
                }
            }
        }
    }

调用:

    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();

            this.Load += Form3_Load;
        }

        void Form3_Load(object sender, EventArgs e)
        {
            MyButton btn = new MyButton();
            btn.Name = "myBtn";
            btn.Width = this.Width;
            btn.Height = this.Height;
            btn.Location = new Point(5, 5);
            this.Controls.Add(btn);

        }

        private void button1_Click(object sender, EventArgs e)
        {
            MyButton btn = this.Controls["myBtn"] as MyButton;
            Random r = new Random();
            btn.m_MyCircle.Add(new MyCircle { Position = new Point(r.Next(0, this.Width / 2), r.Next(this.Height / 2)), Radius = 10 });
        }


    }

我姓区不姓区 2012-11-14
  • 打赏
  • 举报
回复
 public void Add(myRect rect)
            {
                List.Add(rect);
                //试试在这里进行重绘
            }
eric1162640737 2012-11-14
  • 打赏
  • 举报
回复
由于要求MyRect要是只读属性,不能执行invalidate,即使我将它改成非只读属性,并在set{}中添加invalidate方法,它也并不执行.大家帮帮忙
加载更多回复(1)

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧